This is the mail archive of the glibc-cvs@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]

GNU C Library master sources branch master updated. glibc-2.22-340-g8afdb7a


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  8afdb7ac1ecadf82abdb16a5fcfadf9537ca3d84 (commit)
      from  939e092a9e46e6a8bb3d7dc3cf165f384b598f46 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8afdb7ac1ecadf82abdb16a5fcfadf9537ca3d84

commit 8afdb7ac1ecadf82abdb16a5fcfadf9537ca3d84
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Wed Oct 7 23:45:29 2015 +0000

    Fix lround, llround missing exceptions close to overflow threshold (bug 19088).
    
    The dbl-64, ldbl-96 and ldbl-128 implementations of lround and llround
    fail to produce "invalid" exceptions in cases where the rounded result
    overflows the target type, but truncating the floating-point argument
    to the next integer towards zero does not overflow it (so in
    particular casts do not produce such exceptions).  (This issue cannot
    arise for float, or for double with 64-bit target type, or for ldbl-96
    with 64-bit target type and negative arguments, because of
    insufficient precision in the floating-point type for arguments with
    the relevant property to exist.)
    
    This patch fixes these problems by inserting checks for the special
    cases that can occur in each implementation, and explicitly raising
    FE_INVALID (and avoiding the cast if it might raise spurious
    FE_INEXACT).
    
    Tested for x86_64, x86 and mips64.
    
    	[BZ #19088]
    	* sysdeps/ieee754/dbl-64/s_lround.c: Include <fenv.h> and
    	<limits.h>.
    	(__lround) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Include <fenv.h>
    	and <limits.h>.
    	(__lround) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* sysdeps/ieee754/ldbl-128/s_llroundl.c: Include <fenv.h> and
    	<limits.h>.
    	(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* sysdeps/ieee754/ldbl-128/s_lroundl.c: Include <fenv.h> and
    	<limits.h>.
    	(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* sysdeps/ieee754/ldbl-96/s_llroundl.c: Include <fenv.h> and
    	<limits.h>.
    	(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* sysdeps/ieee754/ldbl-96/s_lroundl.c: Include <fenv.h> and
    	<limits.h>.
    	(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
    	overflows but exception would not result from cast.
    	* math/libm-test.inc (lround_test_data): Add more tests.
    	(llround_test_data): Likewise.

diff --git a/ChangeLog b/ChangeLog
index 58069c7..8211682 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2015-10-07  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #19088]
+	* sysdeps/ieee754/dbl-64/s_lround.c: Include <fenv.h> and
+	<limits.h>.
+	(__lround) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Include <fenv.h>
+	and <limits.h>.
+	(__lround) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* sysdeps/ieee754/ldbl-128/s_llroundl.c: Include <fenv.h> and
+	<limits.h>.
+	(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* sysdeps/ieee754/ldbl-128/s_lroundl.c: Include <fenv.h> and
+	<limits.h>.
+	(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* sysdeps/ieee754/ldbl-96/s_llroundl.c: Include <fenv.h> and
+	<limits.h>.
+	(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* sysdeps/ieee754/ldbl-96/s_lroundl.c: Include <fenv.h> and
+	<limits.h>.
+	(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
+	overflows but exception would not result from cast.
+	* math/libm-test.inc (lround_test_data): Add more tests.
+	(llround_test_data): Likewise.
+
 2015-10-07  Steve Ellcey  <sellcey@imgtec.com>
 
 	* timezone/Makefile (CFLAGS-zic.c): Add -Wno-unused-variable.
diff --git a/NEWS b/NEWS
index 30284ba..a3adcfd 100644
--- a/NEWS
+++ b/NEWS
@@ -18,7 +18,7 @@ Version 2.23
   18820, 18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875,
   18887, 18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970,
   18977, 18980, 18981, 18985, 19003, 19012, 19016, 19018, 19032, 19046,
-  19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079, 19085.
+  19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079, 19085, 19088.
 
 * The obsolete header <regexp.h> has been removed.  Programs that require
   this header must be updated to use <regex.h> instead.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 54f62f8..fe74e28 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -8282,6 +8282,123 @@ static const struct test_f_l_data lround_test_data[] =
 #endif
     TEST_f_l (lround, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
     TEST_f_l (lround, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#ifndef TEST_FLOAT
+    TEST_f_l (lround, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_l (lround, 0x7fffffff.4p0, 0x7fffffffLL, ERRNO_UNCHANGED),
+    TEST_f_l (lround, 0x7fffffff.7ffffcp0, 0x7fffffffLL, ERRNO_UNCHANGED),
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, 0x7fffffff.8p0, 0x80000000LL, ERRNO_UNCHANGED),
+    TEST_f_l (lround, 0x7fffffff.cp0, 0x80000000LL, ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, 0x7fffffff.8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, 0x7fffffff.cp0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+    TEST_f_l (lround, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_f_l (lround, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+    TEST_f_l (lround, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#ifndef TEST_FLOAT
+    TEST_f_l (lround, -0x80000000.4p0, -0x80000000LL, ERRNO_UNCHANGED),
+    TEST_f_l (lround, -0x80000000.7ffff8p0, -0x80000000LL, ERRNO_UNCHANGED),
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, -0x80000000.8p0, -0x80000001LL, ERRNO_UNCHANGED),
+    TEST_f_l (lround, -0x80000000.cp0, -0x80000001LL, ERRNO_UNCHANGED),
+    TEST_f_l (lround, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, -0x80000000.8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, -0x80000000.cp0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, -0x80000001p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+#endif
+#if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#else
+    TEST_f_l (lround, -0x80000100p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+    TEST_f_l (lround, -0x80000000.7fffffffp0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_f_l (lround, -0x80000000.7fffffffffffffffffcp0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+    TEST_f_l (lround, -0x80000000.7fffffffffffffffffff8p0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#else
+    TEST_f_l (lround, 0x7fffff8000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#ifndef TEST_FLOAT
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, 0x7ffffffffffffc00p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+#endif
+#ifdef TEST_LDOUBLE
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, 0x7fffffffffffffffp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+    TEST_f_l (lround, 0x7fffffffffffffff.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# if LDBL_MANT_DIG > 64
+#  if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#  else
+    TEST_f_l (lround, 0x7fffffffffffffff.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#  endif
+    TEST_f_l (lround, 0x7fffffffffffffff.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+# if LONG_MAX > 0x7fffffff
+#  if LDBL_MANT_DIG >= 106
+    TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#  endif
+#  if LDBL_MANT_DIG >= 113
+    TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#  endif
+# else
+#  if LDBL_MANT_DIG >= 106
+    TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffep0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#  endif
+#  if LDBL_MANT_DIG >= 113
+    TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#  endif
+# endif
+#endif
+#ifdef TEST_LDOUBLE
+    TEST_f_l (lround, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, -0x8000000000000000.4p0L, LLONG_MIN, ERRNO_UNCHANGED),
+    TEST_f_l (lround, -0x8000000000000000.7fffffffffcp0L, LLONG_MIN, ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, -0x8000000000000000.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, -0x8000000000000000.7fffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+    TEST_f_l (lround, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_l (lround, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+    TEST_f_l (lround, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#ifndef TEST_FLOAT
+    TEST_f_l (lround, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+# if LONG_MAX > 0x7fffffff
+    TEST_f_l (lround, -0x8000000000000000.7fffffffffff8p0L, LLONG_MIN, ERRNO_UNCHANGED),
+# else
+    TEST_f_l (lround, -0x8000000000000000.7fffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+#endif
     TEST_f_l (lround, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_l (lround, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_l (lround, min_value, 0.0, ERRNO_UNCHANGED),
@@ -8492,6 +8609,74 @@ static const struct test_f_L_data llround_test_data[] =
     TEST_f_L (llround, -0x1p63, LLONG_MIN, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_L (llround, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
     TEST_f_L (llround, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_L (llround, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#ifndef TEST_FLOAT
+    TEST_f_L (llround, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffff.4p0, 0x7fffffffLL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffff.7ffffcp0, 0x7fffffffLL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffff.8p0, 0x80000000LL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffff.cp0, 0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+    TEST_f_L (llround, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_f_L (llround, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+    TEST_f_L (llround, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, ERRNO_UNCHANGED),
+#endif
+#ifndef TEST_FLOAT
+    TEST_f_L (llround, -0x80000000.4p0, -0x80000000LL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x80000000.7ffff8p0, -0x80000000LL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x80000000.8p0, -0x80000001LL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x80000000.cp0, -0x80000001LL, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+    TEST_f_L (llround, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+    TEST_f_L (llround, -0x80000000.7fffffffp0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_f_L (llround, -0x80000000.7fffffffffffffffffcp0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+    TEST_f_L (llround, -0x80000000.7fffffffffffffffffff8p0L, -0x80000000LL, ERRNO_UNCHANGED),
+#endif
+    TEST_f_L (llround, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#ifndef TEST_FLOAT
+    TEST_f_L (llround, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#ifdef TEST_LDOUBLE
+    TEST_f_L (llround, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffffffffffff.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# if LDBL_MANT_DIG > 64
+    TEST_f_L (llround, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_L (llround, 0x7fffffffffffffff.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+# endif
+# if LDBL_MANT_DIG >= 106
+    TEST_f_L (llround, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+# endif
+# if LDBL_MANT_DIG >= 113
+    TEST_f_L (llround, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+# endif
+#endif
+#ifdef TEST_LDOUBLE
+    TEST_f_L (llround, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_f_L (llround, -0x8000000000000000.4p0L, LLONG_MIN, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x8000000000000000.7fffffffffcp0L, LLONG_MIN, ERRNO_UNCHANGED),
+    TEST_f_L (llround, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_f_L (llround, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+    TEST_f_L (llround, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#ifndef TEST_FLOAT
+    TEST_f_L (llround, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+    TEST_f_L (llround, -0x8000000000000000.7fffffffffff8p0L, LLONG_MIN, ERRNO_UNCHANGED),
+#endif
     TEST_f_L (llround, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_L (llround, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_L (llround, min_value, 0.0, ERRNO_UNCHANGED),
diff --git a/sysdeps/ieee754/dbl-64/s_lround.c b/sysdeps/ieee754/dbl-64/s_lround.c
index bdc838a..91b17b0 100644
--- a/sysdeps/ieee754/dbl-64/s_lround.c
+++ b/sysdeps/ieee754/dbl-64/s_lround.c
@@ -17,6 +17,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -60,13 +62,33 @@ __lround (double x)
 	  if (j0 == 20)
 	    result = (long int) i0;
 	  else
-	    result = ((long int) i0 << (j0 - 20)) | (j >> (52 - j0));
+	    {
+	      result = ((long int) i0 << (j0 - 20)) | (j >> (52 - j0));
+#ifdef FE_INVALID
+	      if (sizeof (long int) == 4
+		  && sign == 1
+		  && result == LONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
+	    }
 	}
     }
   else
     {
-      /* The number is too large.  It is left implementation defined
-	 what happens.  */
+      /* The number is too large.  Unless it rounds to LONG_MIN,
+	 FE_INVALID must be raised and the return value is
+	 unspecified.  */
+#ifdef FE_INVALID
+      if (sizeof (long int) == 4
+	  && x <= (double) LONG_MIN - 0.5)
+	{
+	  /* If truncation produces LONG_MIN, the cast will not raise
+	     the exception, but may raise "inexact".  */
+	  feraiseexcept (FE_INVALID);
+	  return LONG_MIN;
+	}
+#endif
       return (long int) x;
     }
 
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c
index 390e733..bbc0628 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c
@@ -16,6 +16,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -48,12 +50,30 @@ __lround (double x)
 	  i0 += UINT64_C(0x8000000000000) >> j0;
 
 	  result = i0 >> (52 - j0);
+#ifdef FE_INVALID
+	  if (sizeof (long int) == 4
+	      && sign == 1
+	      && result == LONG_MIN)
+	    /* Rounding brought the value out of range.  */
+	    feraiseexcept (FE_INVALID);
+#endif
 	}
     }
   else
     {
-      /* The number is too large.  It is left implementation defined
-	 what happens.  */
+      /* The number is too large.  Unless it rounds to LONG_MIN,
+	 FE_INVALID must be raised and the return value is
+	 unspecified.  */
+#ifdef FE_INVALID
+      if (sizeof (long int) == 4
+	  && x <= (double) LONG_MIN - 0.5)
+	{
+	  /* If truncation produces LONG_MIN, the cast will not raise
+	     the exception, but may raise "inexact".  */
+	  feraiseexcept (FE_INVALID);
+	  return LONG_MIN;
+	}
+#endif
       return (long int) x;
     }
 
diff --git a/sysdeps/ieee754/ldbl-128/s_llroundl.c b/sysdeps/ieee754/ldbl-128/s_llroundl.c
index 4adc50e..235a433 100644
--- a/sysdeps/ieee754/ldbl-128/s_llroundl.c
+++ b/sysdeps/ieee754/ldbl-128/s_llroundl.c
@@ -18,6 +18,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -60,13 +62,30 @@ __llroundl (long double x)
 	  if (j0 == 48)
 	    result = (long long int) i0;
 	  else
-	    result = ((long long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+	    {
+	      result = ((long long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+#ifdef FE_INVALID
+	      if (sign == 1 && result == LLONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
+	    }
 	}
     }
   else
     {
-      /* The number is too large.  It is left implementation defined
-	 what happens.  */
+      /* The number is too large.  Unless it rounds to LLONG_MIN,
+	 FE_INVALID must be raised and the return value is
+	 unspecified.  */
+#ifdef FE_INVALID
+      if (x <= (long double) LLONG_MIN - 0.5L)
+	{
+	  /* If truncation produces LLONG_MIN, the cast will not raise
+	     the exception, but may raise "inexact".  */
+	  feraiseexcept (FE_INVALID);
+	  return LLONG_MIN;
+	}
+#endif
       return (long long int) x;
     }
 
diff --git a/sysdeps/ieee754/ldbl-128/s_lroundl.c b/sysdeps/ieee754/ldbl-128/s_lroundl.c
index 64b285e..3c6d26a 100644
--- a/sysdeps/ieee754/ldbl-128/s_lroundl.c
+++ b/sysdeps/ieee754/ldbl-128/s_lroundl.c
@@ -18,6 +18,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -47,6 +49,13 @@ __lroundl (long double x)
 	    {
 	      i0 += 0x0000800000000000LL >> j0;
 	      result = i0 >> (48 - j0);
+#ifdef FE_INVALID
+	      if (sizeof (long int) == 4
+		  && sign == 1
+		  && result == LONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
 	    }
 	}
       else if (j0 >= 112)
@@ -60,11 +69,32 @@ __lroundl (long double x)
 	  if (j0 == 48)
 	    result = (long int) i0;
 	  else
-	    result = ((long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+	    {
+	      result = ((long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+#ifdef FE_INVALID
+	      if (sizeof (long int) == 8
+		  && sign == 1
+		  && result == LONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
+	    }
 	}
     }
   else
     {
+      /* The number is too large.  Unless it rounds to LONG_MIN,
+	 FE_INVALID must be raised and the return value is
+	 unspecified.  */
+#ifdef FE_INVALID
+      if (x <= (long double) LONG_MIN - 0.5L)
+	{
+	  /* If truncation produces LONG_MIN, the cast will not raise
+	     the exception, but may raise "inexact".  */
+	  feraiseexcept (FE_INVALID);
+	  return LONG_MIN;
+	}
+#endif
       /* The number is too large.  It is left implementation defined
 	 what happens.  */
       return (long int) x;
diff --git a/sysdeps/ieee754/ldbl-96/s_llroundl.c b/sysdeps/ieee754/ldbl-96/s_llroundl.c
index 8381649..17a3cca 100644
--- a/sysdeps/ieee754/ldbl-96/s_llroundl.c
+++ b/sysdeps/ieee754/ldbl-96/s_llroundl.c
@@ -17,6 +17,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -64,7 +66,14 @@ __llroundl (long double x)
 	    ++result;
 
 	  if (j0 > 31)
-	    result = (result << (j0 - 31)) | (j >> (63 - j0));
+	    {
+	      result = (result << (j0 - 31)) | (j >> (63 - j0));
+#ifdef FE_INVALID
+	      if (sign == 1 && result == LLONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
+	    }
 	}
     }
   else
diff --git a/sysdeps/ieee754/ldbl-96/s_lroundl.c b/sysdeps/ieee754/ldbl-96/s_lroundl.c
index 7a59835..6bfc256 100644
--- a/sysdeps/ieee754/ldbl-96/s_lroundl.c
+++ b/sysdeps/ieee754/ldbl-96/s_lroundl.c
@@ -17,6 +17,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
+#include <limits.h>
 #include <math.h>
 
 #include <math_private.h>
@@ -49,6 +51,13 @@ __lroundl (long double x)
 	    }
 
 	  result = j >> (31 - j0);
+#ifdef FE_INVALID
+	  if (sizeof (long int) == 4
+	      && sign == 1
+	      && result == LONG_MIN)
+	    /* Rounding brought the value out of range.  */
+	    feraiseexcept (FE_INVALID);
+#endif
 	}
     }
   else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
@@ -66,13 +75,33 @@ __lroundl (long double x)
 	  if (j0 == 31)
 	    result = ures;
 	  else
-	    result = (ures << (j0 - 31)) | (j >> (63 - j0));
+	    {
+	      result = (ures << (j0 - 31)) | (j >> (63 - j0));
+#ifdef FE_INVALID
+	      if (sizeof (long int) == 8
+		  && sign == 1
+		  && result == LONG_MIN)
+		/* Rounding brought the value out of range.  */
+		feraiseexcept (FE_INVALID);
+#endif
+	    }
 	}
     }
   else
     {
-      /* The number is too large.  It is left implementation defined
-	 what happens.  */
+      /* The number is too large.  Unless it rounds to LONG_MIN,
+	 FE_INVALID must be raised and the return value is
+	 unspecified.  */
+#ifdef FE_INVALID
+      if (sizeof (long int) == 4
+	  && x <= (long double) LONG_MIN - 0.5L)
+	{
+	  /* If truncation produces LONG_MIN, the cast will not raise
+	     the exception, but may raise "inexact".  */
+	  feraiseexcept (FE_INVALID);
+	  return LONG_MIN;
+	}
+#endif
       return (long int) x;
     }
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                     |   30 ++++
 NEWS                                          |    2 +-
 math/libm-test.inc                            |  185 +++++++++++++++++++++++++
 sysdeps/ieee754/dbl-64/s_lround.c             |   28 ++++-
 sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c |   24 +++-
 sysdeps/ieee754/ldbl-128/s_llroundl.c         |   25 +++-
 sysdeps/ieee754/ldbl-128/s_lroundl.c          |   32 ++++-
 sysdeps/ieee754/ldbl-96/s_llroundl.c          |   11 ++-
 sysdeps/ieee754/ldbl-96/s_lroundl.c           |   35 +++++-
 9 files changed, 358 insertions(+), 14 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


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