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