]> git.eshelyaron.com Git - emacs.git/commitdiff
Port to GCC 8 -fsanitize=undefined
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 18 May 2018 22:45:42 +0000 (15:45 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 18 May 2018 22:49:48 +0000 (15:49 -0700)
In GCC 8, gcc -fsanitize=undefined flags the undefined behavior
that Emacs relies on in its XPNTR and XSYMBOL low-level functions.
Disable undefined sanitization in these functions.  Although this
disabling doesn’t suffice if DEFINE_KEY_OPS_AS_MACROS is true, it
works for -fsanitize=undefined -DINLINING=0, which is good enough.
* src/alloc.c (macro_PNTR_ADD): New macro.
(PNTR_ADD): New function and macro.
The function disables -fsanitize=undefined.
(macro_XPNTR): Use it.
* src/conf_post.h (ATTRIBUTE_NO_SANITIZE_UNDEFINED): New macro.
* src/lisp.h (XSYMBOL): Disable -fsanitize=undefined.

src/alloc.c
src/conf_post.h
src/lisp.h

index 8264e0623cf442ddafcad31a51df97bf0780a69c..231ade5cf80d9fc386a82c13c6d52f5888ee4f01 100644 (file)
@@ -503,18 +503,34 @@ pointer_align (void *ptr, int alignment)
   return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
 }
 
-/* Extract the pointer hidden within O.  Define this as a function, as
-   functions are cleaner and can be used in debuggers.  Also, define
-   it as a macro if being compiled with GCC without optimization, for
-   performance in that case.  macro_XPNTR is private to this section
-   of code.  */
+/* Define PNTR_ADD and XPNTR as functions, which are cleaner and can
+   be used in debuggers.  Also, define them as macros if
+   DEFINE_KEY_OPS_AS_MACROS, for performance in that case.
+   The macro_* macros are private to this section of code.  */
+
+/* Add a pointer an an integer without complaint about a pointer going
+   out of range of the underlying array.  */
+
+#define macro_PNTR_ADD(p, i) ((p) + (i))
+
+static char * ATTRIBUTE_NO_SANITIZE_UNDEFINED ATTRIBUTE_UNUSED
+PNTR_ADD (char *p, EMACS_UINT i)
+{
+  return macro_PNTR_ADD (p, i);
+}
+
+#if DEFINE_KEY_OPS_AS_MACROS
+# define PNTR_ADD(p, i) macro_PNTR_ADD (p, i)
+#endif
+
+/* Extract the pointer hidden within O.  */
 
 #define macro_XPNTR(o)                                                 \
   ((void *) \
    (SYMBOLP (o)                                                               \
-    ? ((char *) lispsym                                                       \
-       - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS))     \
-       + XLI (o))                                                     \
+    ? PNTR_ADD ((char *) lispsym,                                     \
+               (XLI (o)                                                \
+                - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)))) \
     : (char *) XLP (o) - (XLI (o) & ~VALMASK)))
 
 static ATTRIBUTE_UNUSED void *
index 00e283d289c18fd243855411f8710bf27b326165..bf2cfc4f05f18e53b3a114f66742358a6b4b09d5 100644 (file)
@@ -67,6 +67,7 @@ typedef bool bool_bf;
 # define __has_attribute_externally_visible GNUC_PREREQ (4, 1, 0)
 # define __has_attribute_no_address_safety_analysis false
 # define __has_attribute_no_sanitize_address GNUC_PREREQ (4, 8, 0)
+# define __has_attribute_no_sanitize_undefined GNUC_PREREQ (4, 9, 0)
 #endif
 
 /* Simulate __has_builtin on compilers that lack it.  It is used only
@@ -338,6 +339,17 @@ extern int emacs_setenv_TZ (char const *);
 # define ATTRIBUTE_NO_SANITIZE_ADDRESS
 #endif
 
+/* Attribute of functions whose undefined behavior should not be sanitized.  */
+
+#if __has_attribute (no_sanitize_undefined)
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined))
+#elif __has_attribute (no_sanitize)
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED \
+    __attribute__ ((no_sanitize ("undefined")))
+#else
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
+#endif
+
 /* gcc -fsanitize=address does not work with vfork in Fedora 25 x86-64.
    For now, assume that this problem occurs on all platforms.  */
 #if ADDRESS_SANITIZER && !defined vfork
index a18b64a588f6fa6d97b2651e460e4652cc0feaf3..ee2e72d32b7eeb1e7d90929fa31f4576e6f365ce 100644 (file)
@@ -900,7 +900,7 @@ INLINE bool
   return lisp_h_SYMBOLP (x);
 }
 
-INLINE struct Lisp_Symbol *
+INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED
 (XSYMBOL) (Lisp_Object a)
 {
 #if USE_LSB_TAG