bug-m4
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]