This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Set errno for y1 overflow (bug 17050)


This patch fixes bug 17050, missing errno setting for y1 overflow (for
small positive arguments).  An appropriate check is added for overflow
directly in the __ieee754_y1 implementation, similar to the check
present for yn (doing it there rather than in the wrapper also avoids
yn needing to repeat the check when called for order 1 or -1 and it
uses __ieee754_y1).

Tested x86_64 and x86; no ulps update needed.  Also tested for mips64
to verify the ldbl-128 fix (the ldbl-128ibm code just #includes the
ldbl-128 file).

(auto-libm-test-out diffs omitted below.)

2014-06-12  Joseph Myers  <joseph@codesourcery.com>

	[BZ #17050]
	* sysdeps/ieee754/dbl-64/e_j1.c: Include <errno.h>.
	(__ieee754_y1): Set errno if return value overflows.
	* sysdeps/ieee754/flt-32/e_j1f.c: Include <errno.h>.
	(__ieee754_y1f): Set errno if return value overflows.
	* sysdeps/ieee754/ldbl-128/e_j1l.c: Include <errno.h>.
	(__ieee754_y1l): Set errno if return value overflows.
	* sysdeps/ieee754/ldbl-96/e_j1l.c: Include <errno.h>.
	(__ieee754_y1l): Set errno if return value overflows.
	* math/auto-libm-test-in: Add more tests of y0, y1 and yn.
	* math/auto-libm-test-out: Regenerated.

diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 6edad5a..ce50e39 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -2393,6 +2393,8 @@ y0 0x1p-80
 y0 0x1p-90
 y0 0x1p-100
 y0 0x1p-110
+y0 min
+y0 min_subnorm
 
 y1 0.125
 y1 0.75
@@ -2417,6 +2419,8 @@ y1 0x1p-80
 y1 0x1p-90
 y1 0x1p-100
 y1 0x1p-110
+y1 min
+y1 min_subnorm
 
 # yn (0, x) == y0 (x).
 yn 0 0.125
@@ -2461,3 +2465,22 @@ yn 2 0x1.ffff62p+99
 yn 2 0x1p127
 yn 2 0x1p1023
 yn 2 0x1p16383
+
+yn 0 min
+yn 0 min_subnorm
+yn 1 min
+yn 1 min_subnorm
+yn -1 min
+yn -1 min_subnorm
+yn 2 min
+yn 2 min_subnorm
+yn -2 min
+yn -2 min_subnorm
+yn 17 min
+yn 17 min_subnorm
+yn -17 min
+yn -17 min_subnorm
+yn 42 min
+yn 42 min_subnorm
+yn -42 min
+yn -42 min_subnorm
diff --git a/sysdeps/ieee754/dbl-64/e_j1.c b/sysdeps/ieee754/dbl-64/e_j1.c
index bc7ca06..b7b8a9a 100644
--- a/sysdeps/ieee754/dbl-64/e_j1.c
+++ b/sysdeps/ieee754/dbl-64/e_j1.c
@@ -58,6 +58,7 @@
  *	   by method mentioned above.
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -205,7 +206,10 @@ __ieee754_y1 (double x)
     }
   if (__glibc_unlikely (ix <= 0x3c900000))              /* x < 2**-54 */
     {
-      return (-tpi / x);
+      z = -tpi / x;
+      if (__isinf (z))
+	__set_errno (ERANGE);
+      return z;
     }
   z = x * x;
   u1 = U0[0] + z * U0[1]; z2 = z * z;
diff --git a/sysdeps/ieee754/flt-32/e_j1f.c b/sysdeps/ieee754/flt-32/e_j1f.c
index a180968..920e4b8 100644
--- a/sysdeps/ieee754/flt-32/e_j1f.c
+++ b/sysdeps/ieee754/flt-32/e_j1f.c
@@ -13,6 +13,7 @@
  * ====================================================
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -135,7 +136,10 @@ __ieee754_y1f(float x)
 		return z;
 	}
 	if(__builtin_expect(ix<=0x33000000, 0)) {    /* x < 2**-25 */
-	    return(-tpi/x);
+	    z = -tpi / x;
+	    if (__isinff (z))
+		__set_errno (ERANGE);
+	    return z;
 	}
 	z = x*x;
 	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
diff --git a/sysdeps/ieee754/ldbl-128/e_j1l.c b/sysdeps/ieee754/ldbl-128/e_j1l.c
index 1264c95..f24dfa9 100644
--- a/sysdeps/ieee754/ldbl-128/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128/e_j1l.c
@@ -95,6 +95,7 @@
     License along with this library; if not, see
     <http://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 #include <float.h>
@@ -852,7 +853,12 @@ __ieee754_y1l (long double x)
     }
   xx = fabsl (x);
   if (xx <= 0x1p-114)
-    return -TWOOPI / x;
+    {
+      z = -TWOOPI / x;
+      if (__isinfl (z))
+	__set_errno (ERANGE);
+      return z;
+    }
   if (xx <= 2.0L)
     {
       /* 0 <= x <= 2 */
diff --git a/sysdeps/ieee754/ldbl-96/e_j1l.c b/sysdeps/ieee754/ldbl-96/e_j1l.c
index 5c0a2e1..88fcf13 100644
--- a/sysdeps/ieee754/ldbl-96/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-96/e_j1l.c
@@ -71,6 +71,7 @@
  *	   by method mentioned above.
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -234,7 +235,10 @@ __ieee754_y1l (long double x)
     }
   if (__glibc_unlikely (ix <= 0x3fbe))
     {				/* x < 2**-65 */
-      return (-tpi / x);
+      z = -tpi / x;
+      if (__isinfl (z))
+	__set_errno (ERANGE);
+      return z;
     }
   z = x * x;
  u = U0[0] + z * (U0[1] + z * (U0[2] + z * (U0[3] + z * (U0[4] + z * U0[5]))));

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]