This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Set up errno properly for yn
- From: Marek Polacek <polacek at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Wed, 9 May 2012 18:58:29 +0200
- Subject: [PATCH] Set up errno properly for yn
This is a stab at fixing the bug 6808. The problem is that we weren't
setting errno to ERANGE when the second argument is DBL_MIN/FLT_MIN.
I had to use the fetestexcept function, since the FE_OVERFLOW _might_
be set by the GET_HIGH_WORD(high,b) line in the __ieee754_yn function.
I don't know whether this is The Right Thing To Do, it might be
necessary to guard fetestexcept with feholdexcept/feupdateenv, but
that seem quite expensive :/.
I've tried also
if (isfinite (b) != 0)
__set_errno (ERANGE);
but that didn't work.
Also, I've updated the libm-test.inc. Regtested on x86_64-linux,
don't know about i?86.
2012-05-08 Marek Polacek <polacek@redhat.com>
[BZ #6808]
* sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_yn): Set errno to
ERANGE when FE_OVERFLOW was detected.
* math/libm-test.inc (yn_test): Add another test.
--- libc/math/libm-test.inc.mp 2012-05-08 18:11:20.156680614 +0200
+++ libc/math/libm-test.inc 2012-05-09 17:53:24.274229270 +0200
@@ -8348,8 +8348,13 @@ yn_test (void)
TEST_ff_f (yn, 10, 2.0, -129184.542208039282635913145923304214L);
TEST_ff_f (yn, 10, 10.0, -0.359814152183402722051986577343560609L);
- END (yn);
+#ifdef TEST_DOUBLE
+ errno = 0;
+ TEST_ff_f (yn, 10, min_value, minus_infty, OVERFLOW_EXCEPTION);
+ check_int ("errno for yn(10,-min) == ERANGE", errno, ERANGE, 0, 0, 0);
+#endif
+ END (yn);
}
--- libc/sysdeps/ieee754/dbl-64/e_jn.c.mp 2012-05-08 16:54:56.867427923 +0200
+++ libc/sysdeps/ieee754/dbl-64/e_jn.c 2012-05-09 17:32:37.826775331 +0200
@@ -36,6 +36,7 @@
*
*/
+#include <errno.h>
#include <math.h>
#include <math_private.h>
@@ -276,6 +277,9 @@ __ieee754_yn(int n, double x)
GET_HIGH_WORD(high,b);
a = temp;
}
+ /* If FE_OVERFLOW is set, set up errno accordingly. */
+ if (fetestexcept (FE_OVERFLOW) != 0)
+ __set_errno (ERANGE);
}
if(sign>0) return b; else return -b;
}
Marek