This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix tgamma errno setting on domain error (bug 6809)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Thu, 9 May 2013 22:32:26 +0000
- Subject: Fix tgamma errno setting on domain error (bug 6809)
Many of the libm errno-setting bugs have fixes slightly complicated by
needing to fix .S implementations of functions for various
architectures, or needing to work out how to handle setting errno to
ERANGE for finite subnormal results (either don't use
__kernel_standard for the errno setting in this case, or the nonzero
underflowed result needs passing to __kernel_standard so that it gets
preserved) - although they are certainly still worth fixing.
Bug 6809 however, about tgamma domain errors for an argument of -Inf
not setting errno, doesn't run into those issues, and this patch fixes
it simply by adjusting the tests in the wrappers for when to use the
__kernel_standard functions. Tested x86_64 and x86.
2013-05-09 Joseph Myers <joseph@codesourcery.com>
[BZ #6809]
* math/w_tgamma.c (__tgamma): Also call __kernel_standard for
negative infinity argument.
* math/w_tgammaf.c (__tgammaf): Also call __kernel_standard_f for
negative infinity argument.
* math/w_tgammal.c (__tgammal): Also call __kernel_standard_l for
negative infinity argument.
* math/libm-test.inc (tgamma_test): Expect errno to be set for
domain errors.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index c508af6..1ff59e0 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -13615,9 +13615,9 @@ tgamma_test (void)
TEST_f_f (tgamma, 0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
TEST_f_f (tgamma, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
/* tgamma (x) == qNaN plus invalid exception for integer x <= 0. */
- TEST_f_f (tgamma, -2, qnan_value, INVALID_EXCEPTION);
- TEST_f_f (tgamma, -max_value, qnan_value, INVALID_EXCEPTION);
- TEST_f_f (tgamma, minus_infty, qnan_value, INVALID_EXCEPTION);
+ TEST_f_f (tgamma, -2, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM);
+ TEST_f_f (tgamma, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM);
+ TEST_f_f (tgamma, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM);
TEST_f_f (tgamma, qnan_value, qnan_value);
TEST_f_f (tgamma, 0.5, M_SQRT_PIl);
diff --git a/math/w_tgamma.c b/math/w_tgamma.c
index 976b5fb..6b6c7c5 100644
--- a/math/w_tgamma.c
+++ b/math/w_tgamma.c
@@ -24,7 +24,8 @@ __tgamma(double x)
int local_signgam;
double y = __ieee754_gamma_r(x,&local_signgam);
- if(__builtin_expect(!__finite(y), 0)&&__finite(x)
+ if(__builtin_expect(!__finite(y), 0)
+ && (__finite (x) || __isinf (x) < 0)
&& _LIB_VERSION != _IEEE_) {
if (x == 0.0)
return __kernel_standard(x,x,50); /* tgamma pole */
diff --git a/math/w_tgammaf.c b/math/w_tgammaf.c
index 4814135..8bb553e 100644
--- a/math/w_tgammaf.c
+++ b/math/w_tgammaf.c
@@ -22,7 +22,8 @@ __tgammaf(float x)
int local_signgam;
float y = __ieee754_gammaf_r(x,&local_signgam);
- if(__builtin_expect(!__finitef(y), 0) && __finitef(x)
+ if(__builtin_expect(!__finitef(y), 0)
+ && (__finitef (x) || __isinff (x) < 0)
&& _LIB_VERSION != _IEEE_) {
if (x == (float)0.0)
/* tgammaf pole */
diff --git a/math/w_tgammal.c b/math/w_tgammal.c
index 86adab2..72b247d 100644
--- a/math/w_tgammal.c
+++ b/math/w_tgammal.c
@@ -27,7 +27,8 @@ __tgammal(long double x)
int local_signgam;
long double y = __ieee754_gammal_r(x,&local_signgam);
- if(__builtin_expect(!__finitel(y), 0) && __finitel(x)
+ if(__builtin_expect(!__finitel(y), 0)
+ && (__finitel (x) || __isinfl (x) < 0)
&& _LIB_VERSION != _IEEE_) {
if(x==0.0)
return __kernel_standard_l(x,x,250); /* tgamma pole */
--
Joseph S. Myers
joseph@codesourcery.com