This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix j1, jn missing errno setting on underflow (bug 18611) [committed]
- From: Joseph Myers <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Fri, 23 Oct 2015 21:38:16 +0000
- Subject: Fix j1, jn missing errno setting on underflow (bug 18611) [committed]
- Authentication-results: sourceware.org; auth=none
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. Committed.
(auto-libm-test-out diffs omitted below.)
2015-10-23 Joseph Myers <joseph@codesourcery.com>
[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.
diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 3d7143f..b5308e3 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -2424,11 +2424,10 @@ j1 0x1p-60
j1 0x1p-100
j1 0x1p-600
j1 0x1p-10000
-# Bug 18611: errno setting may be missing.
-j1 min missing-errno
-j1 -min missing-errno
-j1 min_subnorm missing-errno
-j1 -min_subnorm missing-errno
+j1 min
+j1 -min
+j1 min_subnorm
+j1 -min_subnorm
# jn (0, x) == j0 (x).
jn 0 -1.0
@@ -2459,11 +2458,10 @@ jn 1 1.5
jn 1 2.0
jn 1 8.0
jn 1 10.0
-# Bug 18611: errno setting may be missing.
-jn 1 min missing-errno
-jn 1 -min missing-errno
-jn 1 min_subnorm missing-errno
-jn 1 -min_subnorm missing-errno
+jn 1 min
+jn 1 -min
+jn 1 min_subnorm
+jn 1 -min_subnorm
jn 3 -1.0
jn 3 0.0
@@ -2504,11 +2502,10 @@ jn -2 -1
jn -3 -1
jn -4 -1
-# Bug 18611: errno setting may be missing.
-jn 10 min missing-errno
-jn 10 -min missing-errno
-jn 10 min_subnorm missing-errno
-jn 10 -min_subnorm missing-errno
+jn 10 min
+jn 10 -min
+jn 10 min_subnorm
+jn 10 -min_subnorm
lgamma max
lgamma 1
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;
--
Joseph S. Myers
joseph@codesourcery.com