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]

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


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