[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Integer wraparound bug with eval on OS X
From: |
Eric Blake |
Subject: |
Re: Integer wraparound bug with eval on OS X |
Date: |
Thu, 24 May 2007 07:24:29 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.10) Gecko/20070221 Thunderbird/1.5.0.10 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Gary,
According to Eric Blake on 5/1/2007 6:48 AM:
> According to Gary V. Vaughan on 4/30/2007 10:49 AM:
>> Hi Eric,
>
>> I think your recent patch to eval has either broken something, or else
>> tickled a long standing bug. Using the latest gnulib and m4 HEAD, test
>> 135 is failing.
>
>
>> eval(-4 >> 65)
>> -1
>> eval(-4 >> 64)
>> -1
>> eval(-4 >> 63)
>> -1
>
> It looks like the failure is due to undefined C code (shifting by an
> amount larger than the width of the type), and that the testsuite is just
> tickling a long-standing bug. branch-1_4 is immune because it
> intentionally masks the shift amount to bring it back into width, so I
> will have to port some of that code to HEAD. Thanks for the heads-up on this.
Fixed like so, and sorry for the delay:
2007-05-24 Eric Blake <address@hidden>
Provide consistent shift semantics regardless of hardware.
* modules/m4.c (numb_lshift, numb_rshift, numb_urshift): Mask
before shifting.
(number, unumber): Always use [u]intmax_t.
Reported by Gary V. Vaughan.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGVZIN84KuGfSFAYARAvl2AJ9a3ggUZULcgrqr5mkn+Oo6b08B0ACfUyDl
yD393QiGMHKeAmNUC6WilGM=
=FdqY
-----END PGP SIGNATURE-----
Index: modules/m4.c
===================================================================
RCS file: /sources/m4/m4/modules/m4.c,v
retrieving revision 1.107
diff -u -p -r1.107 m4.c
--- modules/m4.c 24 May 2007 12:54:13 -0000 1.107
+++ modules/m4.c 24 May 2007 13:24:04 -0000
@@ -100,14 +100,8 @@ extern void m4_make_temp (m4 *contex
BUILTIN (undivert, false, false, false, 0, -1 ) \
-#if defined(SIZEOF_LONG_LONG_INT) && SIZEOF_LONG_LONG_INT > 0
-/* Use GNU long long int if available. */
-typedef long long int number;
-typedef unsigned long long int unumber;
-#else
-typedef long int number;
-typedef unsigned long int unumber;
-#endif
+typedef intmax_t number;
+typedef uintmax_t unumber;
static void include (m4 *context, int argc, m4_symbol_value **argv,
bool silent);
@@ -1106,10 +1100,21 @@ M4BUILTIN_HANDLER (translit)
does not support. */
#define numb_invert(x) return NEGATIVE_EXPONENT
-#define numb_lshift(c, x, y) (*(x) = (*(x) << *(y)))
-#define numb_rshift(c, x, y) (*(x) = (*(x) >> *(y)))
-#define numb_urshift(c, x, y) \
- (*(x) = (number) ((unumber) *(x) >> (unumber) *(y)))
+/* Minimize undefined C behavior (shifting by a negative number,
+ shifting by the width or greater, left shift overflow, or
+ right shift of a negative number). Implement Java 32-bit
+ wrap-around semantics. This code assumes that the
+ implementation-defined overflow when casting unsigned to
+ signed is a silent twos-complement wrap-around. */
+#define shift_mask (sizeof (number) * CHAR_BIT - 1)
+#define numb_lshift(c, x, y) \
+ (*(x) = (number) ((unumber) *(x) << (*(y) & shift_mask)))
+#define numb_rshift(c, x, y) \
+ (*(x) = (number) (*(x) < 0 \
+ ? ~(~(unumber) *(x) >> (*(y) & shift_mask)) \
+ : (unumber) *(x) >> (*(y) & shift_mask)))
+#define numb_urshift(c, x, y) \
+ (*(x) = (number) ((unumber) *(x) >> (*(y) & shift_mask)))
/* The function ntoa () converts VALUE to a signed ascii representation in
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Integer wraparound bug with eval on OS X,
Eric Blake <=