summary refs log tree commit diff
diff options
context:
space:
mode:
-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