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/ieee754 | |
parent | 846d9a4a3acdb4939ca7bf6aed48f9f6f26911be (diff) | |
download | glibc-c643db8792102d1a2efad109f58139977d8608d6.zip glibc-c643db8792102d1a2efad109f58139977d8608d6.tar.gz glibc-c643db8792102d1a2efad109f58139977d8608d6.tar.bz2 |
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/ieee754')
-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 7f80b3c..4827fbf 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 d6ab0bc..3fecf82 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 e24024f..f359a3d 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 d18922a..4e63477 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 70ecf5e..f5b04c0 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 ee5a16b..98669e6 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 c33bc19..4a8ccb0 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 1bca949..e8a7349 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 ed2068b..92f9692 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; |