On 01/05/2017 04:18 PM, Nelson H. F. Beebe wrote:
> I want to report a clang
> issue that showed up on surprisingly many platforms, and with multiple
> versions of clang, but not with all clangs on all platforms:  linking
> with lib/xmalloc.o produces this report:
>
>       lib/libsed.a(xmalloc.o): In function `xnmalloc':
>       lib/xmalloc.c:(.text+0x71): undefined reference to `__muloti4'

Thanks, this turns out to be LLVM bug 16404, an unfixed bug I wish I'd
known. I installed the attached patches to Gnulib to stop using
integer-overflow builtins on Clang, which should work around the LLVM
bug. In the meantime, on Fedora you can work around the sed problem by
installing the Clang-related compiler-rt package and by building with
LDFLAGS=-rtlib=compiler-rt, admittedly quite an annoyance. (I don't know
why Clang sometimes needs special library support to check for size_t
overflow.)

From d3a71f21daec2b137107223c6159bfd3501d0374 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 6 Jan 2017 13:36:57 -0800
Subject: [PATCH] glob, intprops, xalloc: work around Clang bug

Work around LLVM bug 16404, which is still not fixed.
https://llvm.org/bugs/show_bug.cgi?id=16404
Problem reported by Nelson H. F. Beebe.
* lib/glob.c, lib/intprops.h, lib/xalloc-oversized.h (__has_builtin):
Remove.
* lib/glob.c (size_add_wrapv):
* lib/intprops.h (_GL_HAS_BUILTIN_OVERFLOW, _GL_HAS_BUILTIN_OVERFLOW_P):
* lib/xalloc-oversized.h (xalloc_oversized):
Do not use overflow builtins if Clang.
---
 ChangeLog              | 11 +++++++++++
 lib/glob.c             |  6 +-----
 lib/intprops.h         | 10 ++--------
 lib/xalloc-oversized.h | 12 ++----------
 4 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d3dad04..73db88a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2017-01-06  Paul Eggert  <eggert@cs.ucla.edu>
 
+	glob, intprops, xalloc: work around Clang bug
+	Work around LLVM bug 16404, which is still not fixed.
+	https://llvm.org/bugs/show_bug.cgi?id=16404
+	Problem reported by Nelson H. F. Beebe.
+	* lib/glob.c, lib/intprops.h, lib/xalloc-oversized.h (__has_builtin):
+	Remove.
+	* lib/glob.c (size_add_wrapv):
+	* lib/intprops.h (_GL_HAS_BUILTIN_OVERFLOW, _GL_HAS_BUILTIN_OVERFLOW_P):
+	* lib/xalloc-oversized.h (xalloc_oversized):
+	Do not use overflow builtins if Clang.
+
 	dfa: fix 'return' typo
 	Problem reported by Nelson H. F. Beebe.
 	* lib/dfa.c (merge): Fix typo that Sun compilers rejected.
diff --git a/lib/glob.c b/lib/glob.c
index 622fbf6..e91c34d 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -246,10 +246,6 @@ convert_dirent64 (const struct dirent64 *source)
     ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
 #endif
 
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
 /* Set *R = A + B.  Return true if the answer is mathematically
    incorrect due to overflow; in this case, *R is the low order
    bits of the correct answer..  */
@@ -257,7 +253,7 @@ convert_dirent64 (const struct dirent64 *source)
 static bool
 size_add_wrapv (size_t a, size_t b, size_t *r)
 {
-#if 5 <= __GNUC__ || __has_builtin (__builtin_add_overflow)
+#if 5 <= __GNUC__
   return __builtin_add_overflow (a, b, r);
 #else
   *r = a + b;
diff --git a/lib/intprops.h b/lib/intprops.h
index 3b0c5d0..eb06b69 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -23,10 +23,6 @@
 #include <limits.h>
 #include <verify.h>
 
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
 /* Return a value with the common real type of E and V and the value of V.  */
 #define _GL_INT_CONVERT(e, v) (0 * (e) + (v))
 
@@ -241,12 +237,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
    : (max) >> (b) < (a))
 
 /* True if __builtin_add_overflow (A, B, P) works when P is non-null.  */
-#define _GL_HAS_BUILTIN_OVERFLOW \
-  (5 <= __GNUC__ || __has_builtin (__builtin_add_overflow))
+#define _GL_HAS_BUILTIN_OVERFLOW (5 <= __GNUC__)
 
 /* True if __builtin_add_overflow_p (A, B, C) works.  */
-#define _GL_HAS_BUILTIN_OVERFLOW_P \
-  (7 <= __GNUC__ || __has_builtin (__builtin_add_overflow_p))
+#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
 
 /* The _GL*_OVERFLOW macros have the same restrictions as the
    *_RANGE_OVERFLOW macros, except that they do not assume that operands
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
index 6b4e68b..ff0efc6 100644
--- a/lib/xalloc-oversized.h
+++ b/lib/xalloc-oversized.h
@@ -21,11 +21,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-/* Default for (non-Clang) compilers that lack __has_builtin.  */
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
 /* True if N * S would overflow in a size_t calculation,
    or would generate a value larger than PTRDIFF_MAX.
    This expands to a constant expression if N and S are both constants.
@@ -46,13 +41,10 @@ typedef size_t __xalloc_count_type;
    positive and N must be nonnegative.  This is a macro, not a
    function, so that it works correctly even when SIZE_MAX < N.  */
 
-#if 7 <= __GNUC__ || __has_builtin (__builtin_add_overflow_p)
+#if 7 <= __GNUC__
 # define xalloc_oversized(n, s) \
    __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
-#elif ((5 <= __GNUC__ \
-        || (__has_builtin (__builtin_mul_overflow) \
-            && __has_builtin (__builtin_constant_p))) \
-       && !__STRICT_ANSI__)
+#elif 5 <= __GNUC__ && !__STRICT_ANSI__
 # define xalloc_oversized(n, s) \
    (__builtin_constant_p (n) && __builtin_constant_p (s) \
     ? __xalloc_oversized (n, s) \
-- 
2.9.3

Reply via email to