diff options
author | Andrea Corallo <akrl@sdf.org> | 2020-12-27 17:54:57 +0100 |
---|---|---|
committer | Andrea Corallo <akrl@sdf.org> | 2020-12-27 17:54:57 +0100 |
commit | 8fb94630136700aa4e74c7fc212b019d2db380ae (patch) | |
tree | 69b3938a89f450509a7001f45ba3acca057fb40d /lib/intprops.h | |
parent | 271fb8a269aff924070b188f23355d0c368356dd (diff) | |
parent | df882c9701755e2ae063f05d3381de14ae09951e (diff) | |
download | emacs-8fb94630136700aa4e74c7fc212b019d2db380ae.tar.gz emacs-8fb94630136700aa4e74c7fc212b019d2db380ae.tar.bz2 emacs-8fb94630136700aa4e74c7fc212b019d2db380ae.zip |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'lib/intprops.h')
-rw-r--r-- | lib/intprops.h | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/lib/intprops.h b/lib/intprops.h index b27f2eea056..bc2107c9295 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -226,7 +226,9 @@ /* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow (A, B, P) work when P is non-null. */ -#if 5 <= __GNUC__ && !defined __ICC +/* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x, + see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98269>. */ +#if 7 <= __GNUC__ && !defined __ICC # define _GL_HAS_BUILTIN_ADD_OVERFLOW 1 #elif defined __has_builtin # define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow) @@ -244,7 +246,17 @@ /* True if __builtin_add_overflow_p (A, B, C) works, and similarly for __builtin_sub_overflow_p and __builtin_mul_overflow_p. */ -#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) +#if defined __clang__ || defined __ICC +/* Clang 11 lacks __builtin_mul_overflow_p, and even if it did it + would presumably run afoul of Clang bug 16404. ICC 2021.1's + __builtin_add_overflow_p etc. are not treated as integral constant + expressions even when all arguments are. */ +# define _GL_HAS_BUILTIN_OVERFLOW_P 0 +#elif defined __has_builtin +# define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p) +#else +# define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) +#endif /* The _GL*_OVERFLOW macros have the same restrictions as the *_RANGE_OVERFLOW macros, except that they do not assume that operands @@ -377,8 +389,9 @@ _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW) #endif #if _GL_HAS_BUILTIN_MUL_OVERFLOW -# if (9 < __GNUC__ + (3 <= __GNUC_MINOR__) \ - || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) +# if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \ + || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \ + && !defined __ICC) # define INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r) # else /* Work around GCC bug 91450. */ @@ -585,4 +598,33 @@ : (tmin) / (a) < (b)) \ : (tmax) / (b) < (a))) +/* The following macros compute A + B, A - B, and A * B, respectively. + If no overflow occurs, they set *R to the result and return 1; + otherwise, they return 0 and may modify *R. + + Example usage: + + long int result; + if (INT_ADD_OK (a, b, &result)) + printf ("result is %ld\n", result); + else + printf ("overflow\n"); + + A, B, and *R should be integers; they need not be the same type, + and they need not be all signed or all unsigned. + + These macros work correctly on all known practical hosts, and do not rely + on undefined behavior due to signed arithmetic overflow. + + These macros are not constant expressions. + + These macros may evaluate their arguments zero or multiple times, so the + arguments should not have side effects. + + These macros are tuned for B being a constant. */ + +#define INT_ADD_OK(a, b, r) ! INT_ADD_WRAPV (a, b, r) +#define INT_SUBTRACT_OK(a, b, r) ! INT_SUBTRACT_WRAPV (a, b, r) +#define INT_MULTIPLY_OK(a, b, r) ! INT_MULTIPLY_WRAPV (a, b, r) + #endif /* _GL_INTPROPS_H */ |