aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-04-27 18:29:44 -0700
committerPaul Eggert2014-04-27 18:29:44 -0700
commit6ab1b16c54b63d1c4217b6fcea026400029fcc72 (patch)
treee3fef3d5e3f4436b2bc59b1006afc98075da06f0 /src
parent196bfaecb0caffcdbb699694139a97148e90e227 (diff)
downloademacs-6ab1b16c54b63d1c4217b6fcea026400029fcc72.tar.gz
emacs-6ab1b16c54b63d1c4217b6fcea026400029fcc72.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/alloc.c18
-rw-r--r--src/data.c2
-rw-r--r--src/lisp.h19
-rw-r--r--src/regex.c3
5 files changed, 40 insertions, 14 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9d4fd2d6d37..90223d6d103 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12014-04-28 Paul Eggert <eggert@cs.ucla.edu>
2
3 Avoid undefined behavior in signed left shift.
4 This ports to GCC 4.9.0 with -fsanitize=undefined.
5 * alloc.c (bool_vector_fill, SETMARKBIT, UNSETMARKBIT):
6 * data.c (Fash):
7 * regex.c (extract_number):
8 * lisp.h (make_number, XINT):
9 Do not shift a 1 bit left into a sign bit.
10 * alloc.c (struct cons_block, struct float_block): Use unsigned,
11 not int, for gcmarkbits. All uses changed.
12
12014-04-25 Eli Zaretskii <eliz@gnu.org> 132014-04-25 Eli Zaretskii <eliz@gnu.org>
2 14
3 * search.c (Fnewline_cache_check): Don't try to count newlines 15 * search.c (Fnewline_cache_check): Don't try to count newlines
diff --git a/src/alloc.c b/src/alloc.c
index 6bee0c990c4..32d3333cea8 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2131,7 +2131,7 @@ bool_vector_fill (Lisp_Object a, Lisp_Object init)
2131 unsigned char *data = bool_vector_uchar_data (a); 2131 unsigned char *data = bool_vector_uchar_data (a);
2132 int pattern = NILP (init) ? 0 : (1 << BOOL_VECTOR_BITS_PER_CHAR) - 1; 2132 int pattern = NILP (init) ? 0 : (1 << BOOL_VECTOR_BITS_PER_CHAR) - 1;
2133 ptrdiff_t nbytes = bool_vector_bytes (nbits); 2133 ptrdiff_t nbytes = bool_vector_bytes (nbits);
2134 int last_mask = ~ (~0 << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1)); 2134 int last_mask = ~ (~0u << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1));
2135 memset (data, pattern, nbytes - 1); 2135 memset (data, pattern, nbytes - 1);
2136 data[nbytes - 1] = pattern & last_mask; 2136 data[nbytes - 1] = pattern & last_mask;
2137 } 2137 }
@@ -2336,17 +2336,17 @@ make_formatted_string (char *buf, const char *format, ...)
2336 / (sizeof (struct Lisp_Float) * CHAR_BIT + 1)) 2336 / (sizeof (struct Lisp_Float) * CHAR_BIT + 1))
2337 2337
2338#define GETMARKBIT(block,n) \ 2338#define GETMARKBIT(block,n) \
2339 (((block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)] \ 2339 (((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \
2340 >> ((n) % (sizeof (int) * CHAR_BIT))) \ 2340 >> ((n) % (sizeof (unsigned) * CHAR_BIT))) \
2341 & 1) 2341 & 1)
2342 2342
2343#define SETMARKBIT(block,n) \ 2343#define SETMARKBIT(block,n) \
2344 (block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)] \ 2344 ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \
2345 |= 1 << ((n) % (sizeof (int) * CHAR_BIT)) 2345 |= 1u << ((n) % (sizeof (unsigned) * CHAR_BIT)))
2346 2346
2347#define UNSETMARKBIT(block,n) \ 2347#define UNSETMARKBIT(block,n) \
2348 (block)->gcmarkbits[(n) / (sizeof (int) * CHAR_BIT)] \ 2348 ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \
2349 &= ~(1 << ((n) % (sizeof (int) * CHAR_BIT))) 2349 &= ~(1u << ((n) % (sizeof (unsigned) * CHAR_BIT))))
2350 2350
2351#define FLOAT_BLOCK(fptr) \ 2351#define FLOAT_BLOCK(fptr) \
2352 ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1))) 2352 ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1)))
@@ -2358,7 +2358,7 @@ struct float_block
2358{ 2358{
2359 /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job. */ 2359 /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job. */
2360 struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; 2360 struct Lisp_Float floats[FLOAT_BLOCK_SIZE];
2361 int gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof (int) * CHAR_BIT)]; 2361 unsigned gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)];
2362 struct float_block *next; 2362 struct float_block *next;
2363}; 2363};
2364 2364
@@ -2452,7 +2452,7 @@ struct cons_block
2452{ 2452{
2453 /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ 2453 /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */
2454 struct Lisp_Cons conses[CONS_BLOCK_SIZE]; 2454 struct Lisp_Cons conses[CONS_BLOCK_SIZE];
2455 int gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof (int) * CHAR_BIT)]; 2455 unsigned gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)];
2456 struct cons_block *next; 2456 struct cons_block *next;
2457}; 2457};
2458 2458
diff --git a/src/data.c b/src/data.c
index 965ddd215f5..bf863aaed79 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2895,7 +2895,7 @@ In this case, the sign bit is duplicated. */)
2895 if (XINT (count) >= BITS_PER_EMACS_INT) 2895 if (XINT (count) >= BITS_PER_EMACS_INT)
2896 XSETINT (val, 0); 2896 XSETINT (val, 0);
2897 else if (XINT (count) > 0) 2897 else if (XINT (count) > 0)
2898 XSETINT (val, XINT (value) << XFASTINT (count)); 2898 XSETINT (val, XUINT (value) << XFASTINT (count));
2899 else if (XINT (count) <= -BITS_PER_EMACS_INT) 2899 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2900 XSETINT (val, XINT (value) < 0 ? -1 : 0); 2900 XSETINT (val, XINT (value) < 0 ? -1 : 0);
2901 else 2901 else
diff --git a/src/lisp.h b/src/lisp.h
index 4c310f69662..5e0f141cc9c 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -354,7 +354,8 @@ error !;
354# define lisp_h_check_cons_list() ((void) 0) 354# define lisp_h_check_cons_list() ((void) 0)
355#endif 355#endif
356#if USE_LSB_TAG 356#if USE_LSB_TAG
357# define lisp_h_make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS) 357# define lisp_h_make_number(n) \
358 XIL ((EMACS_INT) ((EMACS_UINT) (n) << INTTYPEBITS))
358# define lisp_h_XFASTINT(a) XINT (a) 359# define lisp_h_XFASTINT(a) XINT (a)
359# define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) 360# define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
360# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) 361# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
@@ -665,7 +666,14 @@ LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
665INLINE Lisp_Object 666INLINE Lisp_Object
666make_number (EMACS_INT n) 667make_number (EMACS_INT n)
667{ 668{
668 return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); 669 if (USE_LSB_TAG)
670 {
671 EMACS_UINT u = n;
672 n = u << INTTYPEBITS;
673 }
674 else
675 n &= INTMASK;
676 return XIL (n);
669} 677}
670 678
671/* Extract A's value as a signed integer. */ 679/* Extract A's value as a signed integer. */
@@ -673,7 +681,12 @@ INLINE EMACS_INT
673XINT (Lisp_Object a) 681XINT (Lisp_Object a)
674{ 682{
675 EMACS_INT i = XLI (a); 683 EMACS_INT i = XLI (a);
676 return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS; 684 if (! USE_LSB_TAG)
685 {
686 EMACS_UINT u = i;
687 i = u << INTTYPEBITS;
688 }
689 return i >> INTTYPEBITS;
677} 690}
678 691
679/* Like XINT (A), but may be faster. A must be nonnegative. 692/* Like XINT (A), but may be faster. A must be nonnegative.
diff --git a/src/regex.c b/src/regex.c
index 244924058a0..622db708b98 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -713,7 +713,8 @@ typedef enum
713static int 713static int
714extract_number (re_char *source) 714extract_number (re_char *source)
715{ 715{
716 return (SIGN_EXTEND_CHAR (source[1]) << 8) + source[0]; 716 unsigned leading_byte = SIGN_EXTEND_CHAR (source[1]);
717 return (leading_byte << 8) + source[0];
717} 718}
718 719
719/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. 720/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.