diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/intprops.h | 91 | ||||
-rw-r--r-- | lib/regex_internal.c | 11 | ||||
-rw-r--r-- | lib/verify.h | 28 |
3 files changed, 86 insertions, 44 deletions
diff --git a/lib/intprops.h b/lib/intprops.h index fe67c1f305f..36c6359a21f 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -22,6 +22,18 @@ #include <limits.h> +/* If the compiler lacks __has_builtin, define it well enough for this + source file only. */ +#ifndef __has_builtin +# define __has_builtin(x) _GL_HAS_##x +# if 5 <= __GNUC__ && !defined __ICC +# define _GL_HAS___builtin_add_overflow 1 +# else +# define _GL_HAS___builtin_add_overflow 0 +# endif +# define _GL_TEMPDEF___has_builtin +#endif + /* Return a value with the common real type of E and V and the value of V. Do not evaluate E. */ #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) @@ -220,14 +232,24 @@ ? (a) < (min) >> (b) \ : (max) >> (b) < (a)) -/* True if __builtin_add_overflow (A, B, P) works when P is non-null. */ -#if 5 <= __GNUC__ && !defined __ICC -# define _GL_HAS_BUILTIN_OVERFLOW 1 +/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow + (A, B, P) work when P is non-null. */ +#if __has_builtin (__builtin_add_overflow) +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1 +#else +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0 +#endif + +/* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */ +#ifdef __clang__ +/* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>. */ +# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0 #else -# define _GL_HAS_BUILTIN_OVERFLOW 0 +# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW #endif -/* True if __builtin_add_overflow_p (A, B, C) works. */ +/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for + __builtin_mul_overflow_p and __builtin_mul_overflow_p. */ #define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) /* The _GL*_OVERFLOW macros have the same restrictions as the @@ -351,29 +373,33 @@ /* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. Return 1 if the result overflows. See above for restrictions. */ -#define INT_ADD_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, \ - _GL_INT_ADD_RANGE_OVERFLOW) -#define INT_SUBTRACT_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, \ - _GL_INT_SUBTRACT_RANGE_OVERFLOW) -#define INT_MULTIPLY_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, *, _GL_BUILTIN_MUL_OVERFLOW, \ - _GL_INT_MULTIPLY_RANGE_OVERFLOW) - -/* Like __builtin_mul_overflow, but work around GCC bug 91450. */ -#define _GL_BUILTIN_MUL_OVERFLOW(a, b, r) \ - ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \ - && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \ - ? ((void) __builtin_mul_overflow (a, b, r), 1) \ - : __builtin_mul_overflow (a, b, r)) +#if _GL_HAS_BUILTIN_ADD_OVERFLOW +# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r) +# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r) +#else +# define INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW) +# define INT_SUBTRACT_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW) +#endif +#if _GL_HAS_BUILTIN_MUL_OVERFLOW +/* Work around GCC bug 91450. */ +# define INT_MULTIPLY_WRAPV(a, b, r) \ + ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \ + && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \ + ? ((void) __builtin_mul_overflow (a, b, r), 1) \ + : __builtin_mul_overflow (a, b, r)) +#else +# define INT_MULTIPLY_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) +#endif /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 https://llvm.org/bugs/show_bug.cgi?id=25390 For now, assume all versions of GCC-like compilers generate bogus - warnings for _Generic. This matters only for older compilers that - lack __builtin_add_overflow. */ + warnings for _Generic. This matters only for compilers that + lack relevant builtins. */ #if __GNUC__ # define _GL__GENERIC_BOGUS 1 #else @@ -381,13 +407,10 @@ #endif /* Store the low-order bits of A <op> B into *R, where OP specifies - the operation. BUILTIN is the builtin operation, and OVERFLOW the - overflow predicate. Return 1 if the result overflows. See above - for restrictions. */ -#if _GL_HAS_BUILTIN_OVERFLOW -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r) -#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + the operation and OVERFLOW the overflow predicate. Return 1 if the + result overflows. See above for restrictions. */ +#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ (_Generic \ (*(r), \ signed char: \ @@ -442,7 +465,7 @@ : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0))) # endif -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ (sizeof *(r) == sizeof (signed char) \ ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \ signed char, SCHAR_MIN, SCHAR_MAX, \ @@ -563,4 +586,10 @@ : (tmin) / (a) < (b)) \ : (tmax) / (b) < (a))) +#ifdef _GL_TEMPDEF___has_builtin +# undef __has_builtin +# undef _GL_HAS___builtin_add_overflow +# undef _GL_TEMPDEF___has_builtin +#endif + #endif /* _GL_INTPROPS_H */ diff --git a/lib/regex_internal.c b/lib/regex_internal.c index b592f06725c..0092cc2a468 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -1311,7 +1311,6 @@ re_node_set_insert (re_node_set *set, Idx elem) first element separately to skip a check in the inner loop. */ if (elem < set->elems[0]) { - idx = 0; for (idx = set->nelem; idx > 0; idx--) set->elems[idx] = set->elems[idx - 1]; } @@ -1716,15 +1715,19 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, { if (newstate->entrance_nodes == &newstate->nodes) { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (__glibc_unlikely (newstate->entrance_nodes == NULL)) + re_node_set *entrance_nodes = re_malloc (re_node_set, 1); + if (__glibc_unlikely (entrance_nodes == NULL)) { free_state (newstate); return NULL; } + newstate->entrance_nodes = entrance_nodes; if (re_node_set_init_copy (newstate->entrance_nodes, nodes) != REG_NOERROR) - return NULL; + { + free_state (newstate); + return NULL; + } nctx_nodes = 0; newstate->has_constraint = 1; } diff --git a/lib/verify.h b/lib/verify.h index afdc1ad81f1..06e975ebf65 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -56,6 +56,16 @@ # undef _Static_assert #endif +/* If the compiler lacks __has_builtin, define it well enough for this + source file only. */ +#ifndef __has_builtin +# define __has_builtin(x) _GL_HAS_##x +# define _GL_HAS___builtin_unreachable (4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +# define _GL_HAS___builtin_trap \ + (3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))) +# define _GL_TEMPDEF___has_builtin +#endif + /* Each of these macros verifies that its argument R is nonzero. To be portable, R should be an integer constant expression. Unlike assert (R), there is no run-time overhead. @@ -260,24 +270,17 @@ template <int w> # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) #endif -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - /* Assume that R always holds. Behavior is undefined if R is false, fails to evaluate, or has side effects. Although assuming R can help a compiler generate better code or diagnostics, performance can suffer if R uses hard-to-optimize features such as function calls not inlined by the compiler. */ -#if (__has_builtin (__builtin_unreachable) \ - || 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +#if __has_builtin (__builtin_unreachable) # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) #elif 1200 <= _MSC_VER # define assume(R) __assume (R) -#elif ((defined GCC_LINT || defined lint) \ - && (__has_builtin (__builtin_trap) \ - || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)))) +#elif (defined GCC_LINT || defined lint) && __has_builtin (__builtin_trap) /* Doing it this way helps various packages when configured with --enable-gcc-warnings, which compiles with -Dlint. It's nicer when 'assume' silences warnings even with older GCCs. */ @@ -287,6 +290,13 @@ template <int w> # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) #endif +#ifdef _GL_TEMPDEF___has_builtin +# undef __has_builtin +# undef _GL_HAS___builtin_unreachable +# undef _GL_HAS___builtin_trap +# undef _GL_TEMPDEF___has_builtin +#endif + /* @assert.h omit end@ */ #endif |