summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-11-13 12:59:54 +0000
committerJoseph Myers <joseph@codesourcery.com>2013-11-13 12:59:54 +0000
commit9310c284ae91f13247c9dd7ff58fc2683b9c523d (patch)
tree86478302002c020e38bc75f43abce8ecb37528b1
parent7a2ad8cf392acfcaef319e722dda9101d4d8b6bd (diff)
downloadglibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.tar.gz
glibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.tar.xz
glibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.zip
Fix strtod rounding of half the least subnormal (bug 16151).
-rw-r--r--ChangeLog9
-rw-r--r--NEWS3
-rw-r--r--stdlib/strtod_l.c2
-rw-r--r--stdlib/tst-strtod-round-data8
-rw-r--r--stdlib/tst-strtod-round.c288
5 files changed, 308 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index f1e09b1a7e..c05a9c6143 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-11-13  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #16151]
+	* stdlib/strtod_l.c (round_and_return): Do not consider
+	retval[RETURN_LIBM_SIZE - 1] when determining more_bits for an
+	exponent one less than half the least subnormal exponent.
+	* stdlib/test-strtod-round-data: Add more tests.
+	* stdlib/tst-strtod-round.c (tests): Regenerated.
+
 2013-11-13  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #14143]
diff --git a/NEWS b/NEWS
index 3b441241d6..c6ec27274a 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,8 @@ Version 2.19
   15825, 15844, 15847, 15849, 15855, 15856, 15857, 15859, 15867, 15886,
   15887, 15890, 15892, 15893, 15895, 15897, 15905, 15909, 15917, 15919,
   15921, 15923, 15939, 15948, 15963, 15966, 15985, 15988, 16032, 16034,
-  16036, 16037, 16041, 16071, 16072, 16074, 16078, 16112, 16150, 16153.
+  16036, 16037, 16041, 16071, 16072, 16074, 16078, 16112, 16150, 16151,
+  16153.
 
 * CVE-2012-4412 The strcoll implementation caches indices and rules for
   large collation sequences to optimize multiple passes.  This cache
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index 90541cd48f..c1c5c0db4e 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -228,7 +228,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
 
 	  round_limb = retval[RETURN_LIMB_SIZE - 1];
 	  round_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
-	  for (i = 0; i < RETURN_LIMB_SIZE; ++i)
+	  for (i = 0; i < RETURN_LIMB_SIZE - 1; ++i)
 	    more_bits |= retval[i] != 0;
 	  MPN_ZERO (retval, RETURN_LIMB_SIZE);
 	}
diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data
index 86d460e3b6..a6c37677eb 100644
--- a/stdlib/tst-strtod-round-data
+++ b/stdlib/tst-strtod-round-data
@@ -109,3 +109,11 @@
 -0x0.7p-1074
 -0x0.7p-16445
 -0x0.7p-16494
+0x1p-150
+0x1p-1075
+0x1p-16446
+0x1p-16495
+-0x1p-150
+-0x1p-1075
+-0x1p-16446
+-0x1p-16495
diff --git a/stdlib/tst-strtod-round.c b/stdlib/tst-strtod-round.c
index 9a440264d0..e7aaed17e8 100644
--- a/stdlib/tst-strtod-round.c
+++ b/stdlib/tst-strtod-round.c
@@ -7535,6 +7535,294 @@ static const struct test tests[] = {
 	-0x0p+0L,
 	-0x0p+0L,
 	-0x0p+0L),
+  TEST ("0x1p-150",
+	false,
+	0x0p+0f,
+	0x0p+0f,
+	0x0p+0f,
+	0x8p-152f,
+	true,
+	0x4p-152,
+	0x4p-152,
+	0x4p-152,
+	0x4p-152,
+	true,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	true,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	true,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	true,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	true,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L,
+	0x4p-152L),
+  TEST ("0x1p-1075",
+	false,
+	0x0p+0f,
+	0x0p+0f,
+	0x0p+0f,
+	0x8p-152f,
+	false,
+	0x0p+0,
+	0x0p+0,
+	0x0p+0,
+	0x4p-1076,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	true,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L,
+	true,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	true,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L,
+	0x2p-1076L),
+  TEST ("0x1p-16446",
+	false,
+	0x0p+0f,
+	0x0p+0f,
+	0x0p+0f,
+	0x8p-152f,
+	false,
+	0x0p+0,
+	0x0p+0,
+	0x0p+0,
+	0x4p-1076,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x8p-16448L,
+	true,
+	0x4p-16448L,
+	0x4p-16448L,
+	0x4p-16448L,
+	0x4p-16448L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	true,
+	0x4p-16448L,
+	0x4p-16448L,
+	0x4p-16448L,
+	0x4p-16448L),
+  TEST ("0x1p-16495",
+	false,
+	0x0p+0f,
+	0x0p+0f,
+	0x0p+0f,
+	0x8p-152f,
+	false,
+	0x0p+0,
+	0x0p+0,
+	0x0p+0,
+	0x4p-1076,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x8p-16448L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-16448L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-1076L,
+	false,
+	0x0p+0L,
+	0x0p+0L,
+	0x0p+0L,
+	0x4p-16496L),
+  TEST ("-0x1p-150",
+	false,
+	-0x8p-152f,
+	-0x0p+0f,
+	-0x0p+0f,
+	-0x0p+0f,
+	true,
+	-0x4p-152,
+	-0x4p-152,
+	-0x4p-152,
+	-0x4p-152,
+	true,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	true,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	true,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	true,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	true,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L,
+	-0x4p-152L),
+  TEST ("-0x1p-1075",
+	false,
+	-0x8p-152f,
+	-0x0p+0f,
+	-0x0p+0f,
+	-0x0p+0f,
+	false,
+	-0x4p-1076,
+	-0x0p+0,
+	-0x0p+0,
+	-0x0p+0,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	true,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	true,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	true,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L,
+	-0x2p-1076L),
+  TEST ("-0x1p-16446",
+	false,
+	-0x8p-152f,
+	-0x0p+0f,
+	-0x0p+0f,
+	-0x0p+0f,
+	false,
+	-0x4p-1076,
+	-0x0p+0,
+	-0x0p+0,
+	-0x0p+0,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	false,
+	-0x8p-16448L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	true,
+	-0x4p-16448L,
+	-0x4p-16448L,
+	-0x4p-16448L,
+	-0x4p-16448L,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	true,
+	-0x4p-16448L,
+	-0x4p-16448L,
+	-0x4p-16448L,
+	-0x4p-16448L),
+  TEST ("-0x1p-16495",
+	false,
+	-0x8p-152f,
+	-0x0p+0f,
+	-0x0p+0f,
+	-0x0p+0f,
+	false,
+	-0x4p-1076,
+	-0x0p+0,
+	-0x0p+0,
+	-0x0p+0,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	false,
+	-0x8p-16448L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	false,
+	-0x4p-16448L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	false,
+	-0x4p-1076L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L,
+	false,
+	-0x4p-16496L,
+	-0x0p+0L,
+	-0x0p+0L,
+	-0x0p+0L),
 };
 
 static int