diff options
author | Joseph Myers <joseph@codesourcery.com> | 2015-10-23 21:37:33 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2015-10-23 21:37:33 +0000 |
commit | c643db8792102d1a2efad109f58139977d8608d6 (patch) | |
tree | 174813e539b6cdf509201237756ec2b02e2247ce /sysdeps | |
parent | 846d9a4a3acdb4939ca7bf6aed48f9f6f26911be (diff) | |
download | glibc-c643db8792102d1a2efad109f58139977d8608d6.tar glibc-c643db8792102d1a2efad109f58139977d8608d6.tar.gz glibc-c643db8792102d1a2efad109f58139977d8608d6.tar.bz2 glibc-c643db8792102d1a2efad109f58139977d8608d6.zip |
Fix j1, jn missing errno setting on underflow (bug 18611).
j1 and jn can underflow for small arguments, but fail to set errno
when underflowing to 0. This patch fixes them to set errno in that
case.
Tested for x86_64, x86, mips64 and powerpc.
[BZ #18611]
* sysdeps/ieee754/dbl-64/e_j1.c (__ieee754_j1): Set errno and
avoid excess range and precision on underflow.
* sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_jn): Likewise.
* sysdeps/ieee754/flt-32/e_j1f.c (__ieee754_j1f): Likewise.
* sysdeps/ieee754/flt-32/e_jnf.c (__ieee754_jnf): Likewise.
* sysdeps/ieee754/ldbl-128/e_j1l.c (__ieee754_j1l): Set errno on
underflow.
* sysdeps/ieee754/ldbl-128/e_jnl.c (__ieee754_jnl): Likewise.
* sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise.
* sysdeps/ieee754/ldbl-96/e_j1l.c (__ieee754_j1l): Likewise.
* sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_jnl): Likewise.
* math/auto-libm-test-in: Do not allow missing errno setting for
tests of j1 and jn.
* math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_j1.c | 4 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_jn.c | 6 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/e_j1f.c | 4 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/e_jnf.c | 6 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/e_j1l.c | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/e_jnl.c | 5 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/e_jnl.c | 5 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/e_j1l.c | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/e_jnl.c | 5 |
9 files changed, 32 insertions, 7 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_j1.c b/sysdeps/ieee754/dbl-64/e_j1.c index 7f80b3ced0..4827fbf3d3 100644 --- a/sysdeps/ieee754/dbl-64/e_j1.c +++ b/sysdeps/ieee754/dbl-64/e_j1.c @@ -127,8 +127,10 @@ __ieee754_j1 (double x) { if (huge + x > one) /* inexact if x!=0 necessary */ { - double ret = 0.5 * x; + double ret = math_narrow_eval (0.5 * x); math_check_force_underflow (ret); + if (ret == 0 && x != 0) + __set_errno (ERANGE); return ret; } } diff --git a/sysdeps/ieee754/dbl-64/e_jn.c b/sysdeps/ieee754/dbl-64/e_jn.c index d6ab0bced5..3fecf82f10 100644 --- a/sysdeps/ieee754/dbl-64/e_jn.c +++ b/sysdeps/ieee754/dbl-64/e_jn.c @@ -243,9 +243,13 @@ __ieee754_jn (int n, double x) ret = -b; else ret = b; + ret = math_narrow_eval (ret); } if (ret == 0) - ret = __copysign (DBL_MIN, ret) * DBL_MIN; + { + ret = math_narrow_eval (__copysign (DBL_MIN, ret) * DBL_MIN); + __set_errno (ERANGE); + } else math_check_force_underflow (ret); return ret; diff --git a/sysdeps/ieee754/flt-32/e_j1f.c b/sysdeps/ieee754/flt-32/e_j1f.c index e24024f22e..f359a3d9ba 100644 --- a/sysdeps/ieee754/flt-32/e_j1f.c +++ b/sysdeps/ieee754/flt-32/e_j1f.c @@ -71,8 +71,10 @@ __ieee754_j1f(float x) } if(__builtin_expect(ix<0x32000000, 0)) { /* |x|<2**-27 */ if(huge+x>one) { /* inexact if x!=0 necessary */ - float ret = (float) 0.5 * x; + float ret = math_narrow_eval ((float) 0.5 * x); math_check_force_underflow (ret); + if (ret == 0 && x != 0) + __set_errno (ERANGE); return ret; } } diff --git a/sysdeps/ieee754/flt-32/e_jnf.c b/sysdeps/ieee754/flt-32/e_jnf.c index d18922aa05..4e634778d3 100644 --- a/sysdeps/ieee754/flt-32/e_jnf.c +++ b/sysdeps/ieee754/flt-32/e_jnf.c @@ -167,9 +167,13 @@ __ieee754_jnf(int n, float x) } } if(sgn==1) ret = -b; else ret = b; + ret = math_narrow_eval (ret); } if (ret == 0) - ret = __copysignf (FLT_MIN, ret) * FLT_MIN; + { + ret = math_narrow_eval (__copysignf (FLT_MIN, ret) * FLT_MIN); + __set_errno (ERANGE); + } else math_check_force_underflow (ret); return ret; diff --git a/sysdeps/ieee754/ldbl-128/e_j1l.c b/sysdeps/ieee754/ldbl-128/e_j1l.c index 70ecf5eae3..f5b04c073d 100644 --- a/sysdeps/ieee754/ldbl-128/e_j1l.c +++ b/sysdeps/ieee754/ldbl-128/e_j1l.c @@ -701,6 +701,8 @@ __ieee754_j1l (long double x) { long double ret = x * 0.5L; math_check_force_underflow (ret); + if (ret == 0) + __set_errno (ERANGE); return ret; } if (xx <= 2.0L) diff --git a/sysdeps/ieee754/ldbl-128/e_jnl.c b/sysdeps/ieee754/ldbl-128/e_jnl.c index ee5a16b62e..98669e6e3e 100644 --- a/sysdeps/ieee754/ldbl-128/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128/e_jnl.c @@ -296,7 +296,10 @@ __ieee754_jnl (int n, long double x) ret = b; } if (ret == 0) - ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + { + ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + __set_errno (ERANGE); + } else math_check_force_underflow (ret); return ret; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c index c33bc19d09..4a8ccb044e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c @@ -296,7 +296,10 @@ __ieee754_jnl (int n, long double x) ret = b; } if (ret == 0) - ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + { + ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + __set_errno (ERANGE); + } else math_check_force_underflow (ret); return ret; diff --git a/sysdeps/ieee754/ldbl-96/e_j1l.c b/sysdeps/ieee754/ldbl-96/e_j1l.c index 1bca949e5a..e8a7349cf4 100644 --- a/sysdeps/ieee754/ldbl-96/e_j1l.c +++ b/sysdeps/ieee754/ldbl-96/e_j1l.c @@ -155,6 +155,8 @@ __ieee754_j1l (long double x) { long double ret = 0.5 * x; math_check_force_underflow (ret); + if (ret == 0 && x != 0) + __set_errno (ERANGE); return ret; } } diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c index ed2068b5e2..92f96921a7 100644 --- a/sysdeps/ieee754/ldbl-96/e_jnl.c +++ b/sysdeps/ieee754/ldbl-96/e_jnl.c @@ -289,7 +289,10 @@ __ieee754_jnl (int n, long double x) ret = b; } if (ret == 0) - ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + { + ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + __set_errno (ERANGE); + } else math_check_force_underflow (ret); return ret; |