emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r117027: Avoid undefined behavior in signed left shi


From: Paul Eggert
Subject: [Emacs-diffs] trunk r117027: Avoid undefined behavior in signed left shift.
Date: Mon, 28 Apr 2014 01:29:48 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 117027
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Sun 2014-04-27 18:29:44 -0700
message:
  Avoid undefined behavior in signed left shift.
  
  This ports to GCC 4.9.0 with -fsanitize=undefined.
  * alloc.c (bool_vector_fill, SETMARKBIT, UNSETMARKBIT):
  * data.c (Fash):
  * regex.c (extract_number):
  * lisp.h (make_number, XINT):
  Do not shift a 1 bit left into a sign bit.
  * alloc.c (struct cons_block, struct float_block): Use unsigned,
  not int, for gcmarkbits.  All uses changed.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/alloc.c                    alloc.c-20091113204419-o5vbwnq5f7feedwu-252
  src/data.c                     data.c-20091113204419-o5vbwnq5f7feedwu-251
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
  src/regex.c                    regex.c-20091113204419-o5vbwnq5f7feedwu-518
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-04-25 16:11:07 +0000
+++ b/src/ChangeLog     2014-04-28 01:29:44 +0000
@@ -1,3 +1,15 @@
+2014-04-28  Paul Eggert  <address@hidden>
+
+       Avoid undefined behavior in signed left shift.
+       This ports to GCC 4.9.0 with -fsanitize=undefined.
+       * alloc.c (bool_vector_fill, SETMARKBIT, UNSETMARKBIT):
+       * data.c (Fash):
+       * regex.c (extract_number):
+       * lisp.h (make_number, XINT):
+       Do not shift a 1 bit left into a sign bit.
+       * alloc.c (struct cons_block, struct float_block): Use unsigned,
+       not int, for gcmarkbits.  All uses changed.
+
 2014-04-25  Eli Zaretskii  <address@hidden>
 
        * search.c (Fnewline_cache_check): Don't try to count newlines

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2014-04-16 19:43:46 +0000
+++ b/src/alloc.c       2014-04-28 01:29:44 +0000
@@ -2131,7 +2131,7 @@
       unsigned char *data = bool_vector_uchar_data (a);
       int pattern = NILP (init) ? 0 : (1 << BOOL_VECTOR_BITS_PER_CHAR) - 1;
       ptrdiff_t nbytes = bool_vector_bytes (nbits);
-      int last_mask = ~ (~0 << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1));
+      int last_mask = ~ (~0u << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1));
       memset (data, pattern, nbytes - 1);
       data[nbytes - 1] = pattern & last_mask;
     }
@@ -2336,17 +2336,17 @@
    / (sizeof (struct Lisp_Float) * CHAR_BIT + 1))
 
 #define GETMARKBIT(block,n)                            \
-  (((block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)]       \
-    >> ((n) % (sizeof (int) * CHAR_BIT)))              \
+  (((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)]  \
+    >> ((n) % (sizeof (unsigned) * CHAR_BIT)))         \
    & 1)
 
 #define SETMARKBIT(block,n)                            \
-  (block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)] \
-  |= 1 << ((n) % (sizeof (int) * CHAR_BIT))
+  ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)]   \
+   |= 1u << ((n) % (sizeof (unsigned) * CHAR_BIT)))
 
 #define UNSETMARKBIT(block,n)                          \
-  (block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)] \
-  &= ~(1 << ((n) % (sizeof (int) * CHAR_BIT)))
+  ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)]   \
+   &= ~(1u << ((n) % (sizeof (unsigned) * CHAR_BIT))))
 
 #define FLOAT_BLOCK(fptr) \
   ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1)))
@@ -2358,7 +2358,7 @@
 {
   /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job.  */
   struct Lisp_Float floats[FLOAT_BLOCK_SIZE];
-  int gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof (int) * CHAR_BIT)];
+  unsigned gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)];
   struct float_block *next;
 };
 
@@ -2452,7 +2452,7 @@
 {
   /* Place `conses' at the beginning, to ease up CONS_INDEX's job.  */
   struct Lisp_Cons conses[CONS_BLOCK_SIZE];
-  int gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof (int) * CHAR_BIT)];
+  unsigned gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)];
   struct cons_block *next;
 };
 

=== modified file 'src/data.c'
--- a/src/data.c        2014-04-16 19:43:46 +0000
+++ b/src/data.c        2014-04-28 01:29:44 +0000
@@ -2895,7 +2895,7 @@
   if (XINT (count) >= BITS_PER_EMACS_INT)
     XSETINT (val, 0);
   else if (XINT (count) > 0)
-    XSETINT (val, XINT (value) << XFASTINT (count));
+    XSETINT (val, XUINT (value) << XFASTINT (count));
   else if (XINT (count) <= -BITS_PER_EMACS_INT)
     XSETINT (val, XINT (value) < 0 ? -1 : 0);
   else

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2014-04-22 07:04:34 +0000
+++ b/src/lisp.h        2014-04-28 01:29:44 +0000
@@ -354,7 +354,8 @@
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
 #if USE_LSB_TAG
-# define lisp_h_make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS)
+# define lisp_h_make_number(n) \
+    XIL ((EMACS_INT) ((EMACS_UINT) (n) << INTTYPEBITS))
 # define lisp_h_XFASTINT(a) XINT (a)
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
@@ -665,7 +666,14 @@
 INLINE Lisp_Object
 make_number (EMACS_INT n)
 {
-  return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK);
+  if (USE_LSB_TAG)
+    {
+      EMACS_UINT u = n;
+      n = u << INTTYPEBITS;
+    }
+  else
+    n &= INTMASK;
+  return XIL (n);
 }
 
 /* Extract A's value as a signed integer.  */
@@ -673,7 +681,12 @@
 XINT (Lisp_Object a)
 {
   EMACS_INT i = XLI (a);
-  return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS;
+  if (! USE_LSB_TAG)
+    {
+      EMACS_UINT u = i;
+      i = u << INTTYPEBITS;
+    }
+  return i >> INTTYPEBITS;
 }
 
 /* Like XINT (A), but may be faster.  A must be nonnegative.

=== modified file 'src/regex.c'
--- a/src/regex.c       2014-01-01 07:43:34 +0000
+++ b/src/regex.c       2014-04-28 01:29:44 +0000
@@ -713,7 +713,8 @@
 static int
 extract_number (re_char *source)
 {
-  return (SIGN_EXTEND_CHAR (source[1]) << 8) + source[0];
+  unsigned leading_byte = SIGN_EXTEND_CHAR (source[1]);
+  return (leading_byte << 8) + source[0];
 }
 
 /* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.


reply via email to

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