]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
[BZ #15522] strtod ("nan(N)") returning a sNaN in some cases
authorThomas Schwinge <thomas@codesourcery.com>
Thu, 23 May 2013 16:00:10 +0000 (18:00 +0200)
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Thu, 31 Oct 2013 15:05:55 +0000 (10:05 -0500)
ChangeLog
NEWS
stdlib/strtod_l.c
stdlib/strtof_l.c
stdlib/tst-strtod6.c
sysdeps/ieee754/ldbl-128/strtold_l.c
sysdeps/ieee754/ldbl-128ibm/ieee754.h
sysdeps/ieee754/ldbl-128ibm/strtold_l.c
sysdeps/ieee754/ldbl-64-128/strtold_l.c
sysdeps/ieee754/ldbl-96/strtold_l.c

index 1ffcad440b4fb005f75748bfc40086c0816d4db4..13486b022b45b7d4a8ec22e3aca8c92e82c8162f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2013-08-29  Thomas Schwinge  <thomas@codesourcery.com>
+
+       [BZ #15522] strtod ("nan(N)") returning a sNaN in some cases
+
+       * stdlib/strtof_l.c (SET_MANTISSA): Rewrite.
+       * stdlib/strtod_l.c (SET_MANTISSA): Likewise.
+       * sysdeps/ieee754/ldbl-64-128/strtold_l.c (SET_MANTISSA):
+       Likewise.
+       * sysdeps/ieee754/ldbl-96/strtold_l.c (SET_MANTISSA): Likewise.
+       * sysdeps/ieee754/ldbl-128/strtold_l.c (SET_MANTISSA): Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/strtold_l.c (SET_MANTISSA):
+       Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/ieee754.h
+       (ibm_extended_long_double): Add ieee_nan member.
+       * stdlib/tst-strtod6.c (test): New function, renamed from do_test.
+       (do_test): New function.
+
+       * math/basic-test.c (TEST_CONVERT): New macro, renamed from
+       TEST_TRUNC.
+       (convert_dfsf_test, convert_tfsf_test, convert_tfdf_test): New
+       functions, renamed from truncdfsf_test, trunctfsf_test,
+       trunctfdf_test.
+       (convert_sfdf_test, convert_sftf_test, convert_dftf_test): New
+       functions.
+       (do_test): Run all these.
+
 2013-08-23  Joseph Myers  <joseph@codesourcery.com>
 
        [BZ #15532]
diff --git a/NEWS b/NEWS
index c83a14e980dc3fd239458dfa1d62907f070dc848..18cf053fb036e205c30046a901c2e40b2e8f12da 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,16 @@ See the end for copying conditions.
 
 Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
+<<<<<<< HEAD
+=======
+\f
+Version 2.19
+
+* The following bugs are resolved with this release:
+
+  14699, 15522, 15531, 15532, 15736, 15749, 15797, 15867, 15890, 15897,
+  15905.
+>>>>>>> 0007fc9... [BZ #15522] strtod ("nan(N)") returning a sNaN in some cases
 
 Version 2.18
 
@@ -20,9 +30,9 @@ Version 2.18
   15335, 15336, 15337, 15339, 15342, 15346, 15359, 15361, 15366, 15380,
   15381, 15394, 15395, 15405, 15406, 15409, 15416, 15418, 15419, 15423,
   15424, 15426, 15429, 15431, 15432, 15441, 15442, 15448, 15465, 15480,
-  15485, 15488, 15490, 15492, 15493, 15497, 15506, 15529, 15532, 15536,
-  15553, 15577, 15583, 15618, 15627, 15631, 15654, 15655, 15666, 15667,
-  15674, 15711, 15755, 15759, 15797.
+  15485, 15488, 15490, 15492, 15493, 15497, 15506, 15522, 15529, 15532,
+  15536, 15553, 15577, 15583, 15618, 15627, 15631, 15654, 15655, 15666,
+  15667, 15674, 15711, 15755, 15759, 15797.
 
 * CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal
   has been fixed by disabling the use of pt_chown (Bugzilla #15755).
index 5b41e2b06ed54d5de09a8c0a5f470116bf099c4a..8f60653fb0a722a7214ec5d586174c19a0f16029 100644 (file)
@@ -42,11 +42,10 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
 # define SET_MANTISSA(flt, mant) \
   do { union ieee754_double u;                                               \
        u.d = (flt);                                                          \
-       if ((mant & 0xfffffffffffffULL) == 0)                                 \
-        mant = 0x8000000000000ULL;                                           \
-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;                          \
-       u.ieee.mantissa1 = (mant) & 0xffffffff;                               \
-       (flt) = u.d;                                                          \
+       u.ieee_nan.mantissa0 = (mant) >> 32;                                  \
+       u.ieee_nan.mantissa1 = (mant);                                        \
+       if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)                       \
+        (flt) = u.d;                                                         \
   } while (0)
 #endif
 /* End of configuration part.  */
index 6fb44bd403d89eba1b57d48e2ce90380d26ba1af..c4c1c1f2dd1d7aa74195c7f4f5723c65bc976cc5 100644 (file)
@@ -37,10 +37,9 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
 #define SET_MANTISSA(flt, mant) \
   do { union ieee754_float u;                                                \
        u.f = (flt);                                                          \
-       if ((mant & 0x7fffff) == 0)                                           \
-        mant = 0x400000;                                                     \
-       u.ieee.mantissa = (mant) & 0x7fffff;                                  \
-       (flt) = u.f;                                                          \
+       u.ieee_nan.mantissa = (mant);                                         \
+       if (u.ieee.mantissa != 0)                                             \
+        (flt) = u.f;                                                         \
   } while (0)
 
 #include "strtod_l.c"
index 1d87266a273ebaaf5ce4e936a083f27474ceb5a2..15e79fddfbc0d837ad2123ea1de835908487a22c 100644 (file)
@@ -4,12 +4,13 @@
 #include <string.h>
 
 static int
-do_test (void)
+test (const char str[])
 {
-  static const char str[] = "NaN(blabla)something";
   char *endp;
   int result = 0;
 
+  puts (str);
+
   double d = strtod (str, &endp);
   if (!isnan (d))
     {
@@ -64,5 +65,24 @@ do_test (void)
   return result;
 }
 
+static int
+do_test (void)
+{
+  int result = 0;
+
+  result |= test ("NaN(blabla)something");
+  result |= test ("NaN(1234)something");
+  /* UINT32_MAX.  */
+  result |= test ("NaN(4294967295)something");
+  /* UINT64_MAX.  */
+  result |= test ("NaN(18446744073709551615)something");
+  /* The case of zero is special in that "something" has to be done to make the
+     mantissa different from zero, which would mean infinity instead of
+     NaN.  */
+  result |= test ("NaN(0)something");
+
+  return result;
+}
+
 #define TEST_FUNCTION do_test ()
 #include "../test-skeleton.c"
index 8e0bc031968997171595b54ee87878168337a581..d3a1d1e8624620729bf5572b0643c79671d217e7 100644 (file)
 #define SET_MANTISSA(flt, mant) \
   do { union ieee854_long_double u;                                          \
        u.d = (flt);                                                          \
-       u.ieee.mantissa0 = 0x8000;                                            \
-       u.ieee.mantissa1 = 0;                                                 \
-       u.ieee.mantissa2 = ((mant) >> 32);                                    \
-       u.ieee.mantissa3 = (mant) & 0xffffffff;                               \
-       (flt) = u.d;                                                          \
+       u.ieee_nan.mantissa0 = 0;                                             \
+       u.ieee_nan.mantissa1 = 0;                                             \
+       u.ieee_nan.mantissa2 = (mant) >> 32;                                  \
+       u.ieee_nan.mantissa3 = (mant);                                        \
+       if ((u.ieee.mantissa0 | u.ieee.mantissa1                                      \
+           | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)                      \
+        (flt) = u.d;                                                         \
   } while (0)
 
 #include <strtod_l.c>
index e5644f5d31d2dc5e0825463fc297319cc249e8f7..9e94f53b047201d1490b0df1044df71bd626dbd1 100644 (file)
@@ -199,6 +199,25 @@ union ibm_extended_long_double
        unsigned int mantissa2:20;
        unsigned int mantissa3:32;
       } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      { /* Big endian.  There is no other.  */
+
+       unsigned int negative:1;
+       unsigned int exponent:11;
+       unsigned int quiet_nan:1;
+       /* Together Mantissa0-3 comprise the mantissa.  */
+       unsigned int mantissa0:19;
+       unsigned int mantissa1:32;
+
+       unsigned int negative2:1;
+       unsigned int exponent2:11;
+       /* There is an implied 1 here?  */
+       /* Together these comprise the mantissa.  */
+       unsigned int mantissa2:20;
+       unsigned int mantissa3:32;
+      } ieee_nan;
    };
 
 #define IBM_EXTENDED_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent.  */
index 93415f0f01036077364c5145f6872397e173f766..04e3288571774f0e9da49cc8592376b3b5ef5243 100644 (file)
@@ -44,11 +44,10 @@ libc_hidden_proto (STRTOF)
 # define SET_MANTISSA(flt, mant) \
   do { union ibm_extended_long_double u;                                     \
        u.d = (flt);                                                          \
-       if ((mant & 0xfffffffffffffULL) == 0)                                 \
-        mant = 0x8000000000000ULL;                                           \
-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;                          \
-       u.ieee.mantissa1 = (mant) & 0xffffffff;                               \
-       (flt) = u.d;                                                          \
+       u.ieee_nan.mantissa0 = (mant) >> 32;                                  \
+       u.ieee_nan.mantissa1 = (mant);                                        \
+       if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)                       \
+        (flt) = u.d;                                                         \
   } while (0)
 
 #include <strtod_l.c>
index 8182b2bcd0d895d289730941adc750e2c1243db1..e9b33f2d80174769bc2601d793c04b5dbd83b0dd 100644 (file)
@@ -44,11 +44,13 @@ libc_hidden_proto (STRTOF)
 #define SET_MANTISSA(flt, mant) \
   do { union ieee854_long_double u;                                          \
        u.d = (flt);                                                          \
-       u.ieee.mantissa0 = 0x8000;                                            \
-       u.ieee.mantissa1 = 0;                                                 \
-       u.ieee.mantissa2 = ((mant) >> 32);                                    \
-       u.ieee.mantissa3 = (mant) & 0xffffffff;                               \
-       (flt) = u.d;                                                          \
+       u.ieee_nan.mantissa0 = 0;                                             \
+       u.ieee_nan.mantissa1 = 0;                                             \
+       u.ieee_nan.mantissa2 = (mant) >> 32;                                  \
+       u.ieee_nan.mantissa3 = (mant);                                        \
+       if ((u.ieee.mantissa0 | u.ieee.mantissa1                                      \
+           | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)                      \
+        (flt) = u.d;                                                         \
   } while (0)
 
 #include <strtod_l.c>
index ded84f342b35b093975df3cff116b1f62792fd53..dccf98c4618fe6baf80f5dcea3dfa04b184e67c9 100644 (file)
 #define SET_MANTISSA(flt, mant) \
   do { union ieee854_long_double u;                                          \
        u.d = (flt);                                                          \
-       if ((mant & 0x7fffffffffffffffULL) == 0)                                      \
-        mant = 0x4000000000000000ULL;                                        \
-       u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000;        \
-       u.ieee.mantissa1 = (mant) & 0xffffffff;                               \
-       (flt) = u.d;                                                          \
+       u.ieee_nan.mantissa0 = (mant) >> 32;                                  \
+       u.ieee_nan.mantissa1 = (mant);                                        \
+       if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)                       \
+        (flt) = u.d;                                                         \
   } while (0)
 
 #include <stdlib/strtod_l.c>