about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS2
-rw-r--r--stdlib/strtod_l.c11
3 files changed, 13 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 59464a6478..e87fc225fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,10 @@
 	* localedata/tst-langinfo.sh: Send output to stdout.
 	* localedata/tst-langinfo-static.c: New file.
 
+	[BZ #16965]
+	* stdlib/strtod_l.c (round_and_return): Add code to shift limbs
+	when the shift amount is modulo the limb size.
+
 2014-05-20  Richard Henderson  <rth@redhat.com>
 
 	[BZ #16967]
diff --git a/NEWS b/NEWS
index d9ce8f9af8..8aaf2f4cb5 100644
--- a/NEWS
+++ b/NEWS
@@ -18,7 +18,7 @@ Version 2.20
   16760, 16770, 16786, 16789, 16791, 16799, 16800, 16815, 16823, 16824,
   16831, 16838, 16849, 16854, 16876, 16877, 16885, 16888, 16890, 16912,
   16915, 16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16966,
-  16967.
+  16967, 16965.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index 6707e482a4..3c449c7d54 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -243,9 +243,14 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
 	  more_bits |= ((round_limb & ((((mp_limb_t) 1) << round_bit) - 1))
 			!= 0);
 
-	  (void) __mpn_rshift (retval, &retval[shift / BITS_PER_MP_LIMB],
-			       RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB),
-			       shift % BITS_PER_MP_LIMB);
+	  /* __mpn_rshift requires 0 < shift < BITS_PER_MP_LIMB.  */
+	  if ((shift % BITS_PER_MP_LIMB) != 0)
+	    (void) __mpn_rshift (retval, &retval[shift / BITS_PER_MP_LIMB],
+			         RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB),
+			         shift % BITS_PER_MP_LIMB);
+	  else
+	    for (i = 0; i < RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB); i++)
+	      retval[i] = retval[i + (shift / BITS_PER_MP_LIMB)];
 	  MPN_ZERO (&retval[RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB)],
 		    shift / BITS_PER_MP_LIMB);
 	}