From 310f5bd4294ec3624b425e2c27da6fc730d0e928 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 20 Feb 2012 15:09:58 -0800 Subject: [PATCH] Fix crash due to non-contiguous EMACS_INT (Bug#10780). MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * lisp.h (VALBITS): Move definition up, so that USE_LSB_TAG can use it. (USE_LSB_TAG): Do not define if UINTPTR_MAX >> VALBITS == 0. It's useless in that case, and it can cause problems on hosts that allocate halves of EMACS_INT values separately. Reported by Dan Horák. Diagnosed by Andreas Schwab in . * mem-limits.h (EXCEEDS_LISP_PTR): Define to 0 on hosts where UINTPTR_MAX >> VALBITS == 0. This is required by the above change; it avoids undefined behavior on hosts where shifting right by more than the word width has undefined behavior. --- src/ChangeLog | 14 ++++++++++++++ src/lisp.h | 19 +++++++++++++------ src/mem-limits.h | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 3716aee7d69..911799b2bd2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-02-20 Paul Eggert + + Fix crash due to non-contiguous EMACS_INT (Bug#10780). + * lisp.h (VALBITS): Move definition up, so that USE_LSB_TAG can use it. + (USE_LSB_TAG): Do not define if UINTPTR_MAX >> VALBITS == 0. + It's useless in that case, and it can cause problems on hosts + that allocate halves of EMACS_INT values separately. + Reported by Dan Horák. Diagnosed by Andreas Schwab in + . + * mem-limits.h (EXCEEDS_LISP_PTR): Define to 0 on hosts where + UINTPTR_MAX >> VALBITS == 0. This is required by the above change; + it avoids undefined behavior on hosts where shifting right by more + than the word width has undefined behavior. + 2012-02-19 Chong Yidong * fileio.c (Ffile_name_directory, Ffile_name_nondirectory) diff --git a/src/lisp.h b/src/lisp.h index 366d24a737d..8bfd7071e5f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -168,6 +168,10 @@ extern int suppress_checking EXTERNALLY_VISIBLE; #define GCTYPEBITS 3 #endif +#ifndef VALBITS +#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS) +#endif + #ifndef NO_DECL_ALIGN # ifndef DECL_ALIGN # if HAVE_ATTRIBUTE_ALIGNED @@ -191,7 +195,15 @@ extern int suppress_checking EXTERNALLY_VISIBLE; || defined DARWIN_OS || defined __sun) /* We also need to be able to specify mult-of-8 alignment on static vars. */ # if defined DECL_ALIGN -# define USE_LSB_TAG +/* mark_maybe_object assumes that EMACS_INT values are contiguous, + but this is not true on some hosts where EMACS_INT is wider than a pointer, + as they may allocate the halves of an EMACS_INT separately. + On these hosts USE_LSB_TAG is not needed because the top bits of an + EMACS_INT are unused, so define USE_LSB_TAG only on hosts where it + might be useful. */ +# if UINTPTR_MAX >> VALBITS != 0 +# define USE_LSB_TAG +# endif # endif #endif @@ -309,11 +321,6 @@ enum Lisp_Fwd_Type Lisp_Fwd_Kboard_Obj, /* Fwd to a Lisp_Object field of kboards. */ }; -/* These values are overridden by the m- file on some machines. */ -#ifndef VALBITS -#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS) -#endif - #ifdef USE_LISP_UNION_TYPE #ifndef WORDS_BIGENDIAN diff --git a/src/mem-limits.h b/src/mem-limits.h index 472e591b38d..244592a9768 100644 --- a/src/mem-limits.h +++ b/src/mem-limits.h @@ -34,7 +34,7 @@ extern int etext; #endif extern char *start_of_data (void); -#if defined USE_LSB_TAG +#if defined USE_LSB_TAG || UINTPTR_MAX >> VALBITS == 0 #define EXCEEDS_LISP_PTR(ptr) 0 #elif defined DATA_SEG_BITS #define EXCEEDS_LISP_PTR(ptr) \ -- 2.39.2