summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliot Ronaghan <ronawho@gmail.com>2016-06-17 20:28:39 (GMT)
committerJason Evans <jasone@canonware.com>2016-07-07 20:28:44 (GMT)
commit1167e9eff342d3c0f39bb7e8aabc40a34ac0b2fe (patch)
tree8874ace373376a3de758299e6cbf3c81f54d7de9
parentae3314785bf9726e5a97e5c98f70dcb12e6a7a90 (diff)
downloadjemalloc-1167e9eff342d3c0f39bb7e8aabc40a34ac0b2fe.zip
jemalloc-1167e9eff342d3c0f39bb7e8aabc40a34ac0b2fe.tar.gz
jemalloc-1167e9eff342d3c0f39bb7e8aabc40a34ac0b2fe.tar.bz2
Check for __builtin_unreachable at configure time
Add a configure check for __builtin_unreachable instead of basing its availability on the __GNUC__ version. On OS X using gcc (a real gcc, not the bundled version that's just a gcc front-end) leads to a linker assertion: https://github.com/jemalloc/jemalloc/issues/266 It turns out that this is caused by a gcc bug resulting from the use of __builtin_unreachable(): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57438 To work around this bug, check that __builtin_unreachable() actually works at configure time, and if it doesn't use abort() instead. The check is based on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57438#c21. With this `make check` passes with a homebrew installed gcc-5 and gcc-6.
-rw-r--r--configure.ac17
-rw-r--r--include/jemalloc/internal/jemalloc_internal_defs.h.in6
-rw-r--r--include/jemalloc/internal/util.h22
3 files changed, 29 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index e5164ba..ad7ace5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1038,6 +1038,23 @@ if test "x$enable_cache_oblivious" = "x1" ; then
fi
AC_SUBST([enable_cache_oblivious])
+
+
+JE_COMPILABLE([a program using __builtin_unreachable], [
+void foo (void) {
+ __builtin_unreachable();
+}
+], [
+ {
+ foo();
+ }
+], [je_cv_gcc_builtin_unreachable])
+if test "x${je_cv_gcc_builtin_ffsl}" = "xyes" ; then
+ AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [__builtin_unreachable])
+else
+ AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [abort])
+fi
+
dnl ============================================================================
dnl Check for __builtin_ffsl(), then ffsl(3), and fail if neither are found.
dnl One of those two functions should (theoretically) exist on all platforms
diff --git a/include/jemalloc/internal/jemalloc_internal_defs.h.in b/include/jemalloc/internal/jemalloc_internal_defs.h.in
index 49e2cf0..cebd6a5 100644
--- a/include/jemalloc/internal/jemalloc_internal_defs.h.in
+++ b/include/jemalloc/internal/jemalloc_internal_defs.h.in
@@ -186,6 +186,12 @@
#undef JEMALLOC_TLS
/*
+ * Used to mark unreachable code to quiet "end of non-void" compiler warnings.
+ * Don't use this directly; instead use unreachable() from util.h
+ */
+#undef JEMALLOC_INTERNAL_UNREACHABLE
+
+/*
* ffs*() functions to use for bitmapping. Don't use these directly; instead,
* use ffs_*() from util.h.
*/
diff --git a/include/jemalloc/internal/util.h b/include/jemalloc/internal/util.h
index a0c2203..aee00d6 100644
--- a/include/jemalloc/internal/util.h
+++ b/include/jemalloc/internal/util.h
@@ -61,30 +61,20 @@
# define JEMALLOC_CC_SILENCE_INIT(v)
#endif
-#define JEMALLOC_GNUC_PREREQ(major, minor) \
- (!defined(__clang__) && \
- (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
-#ifndef __has_builtin
-# define __has_builtin(builtin) (0)
-#endif
-#define JEMALLOC_CLANG_HAS_BUILTIN(builtin) \
- (defined(__clang__) && __has_builtin(builtin))
-
#ifdef __GNUC__
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
-# if JEMALLOC_GNUC_PREREQ(4, 6) || \
- JEMALLOC_CLANG_HAS_BUILTIN(__builtin_unreachable)
-# define unreachable() __builtin_unreachable()
-# else
-# define unreachable() abort()
-# endif
#else
# define likely(x) !!(x)
# define unlikely(x) !!(x)
-# define unreachable() abort()
#endif
+#if !defined(JEMALLOC_INTERNAL_UNREACHABLE)
+# error JEMALLOC_INTERNAL_UNREACHABLE should have been defined by configure
+#endif
+
+#define unreachable() JEMALLOC_INTERNAL_UNREACHABLE()
+
#include "jemalloc/internal/assert.h"
/* Use to assert a particular configuration, e.g., cassert(config_debug). */