CMake: Feature-detect __builtin_{add,sub}_overflow

This commit is contained in:
Justin M. Keyes 2019-01-08 22:00:52 +01:00
parent 596f020e90
commit fc4ca5bdd8
2 changed files with 15 additions and 4 deletions

View File

@ -248,6 +248,16 @@ int main(void)
} }
" HAVE_EXECINFO_BACKTRACE) " HAVE_EXECINFO_BACKTRACE)
check_c_source_compiles("
int main(void)
{
int a;
__builtin_add_overflow(a, a, &a);
__builtin_sub_overflow(a, a, &a);
return 0;
}
" HAVE_BUILTIN_ADD_OVERFLOW)
if(MSVC) if(MSVC)
# XXX: /W4 gives too many warnings. #3241 # XXX: /W4 gives too many warnings. #3241
add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)

View File

@ -122,6 +122,7 @@
#endif #endif
/// @def STRICT_ADD /// @def STRICT_ADD
/// @brief Adds (a + b) and stores result in `c`. Aborts on overflow.
/// ///
/// Requires GCC 5+ and Clang 3.8+ /// Requires GCC 5+ and Clang 3.8+
/// https://clang.llvm.org/docs/LanguageExtensions.html /// https://clang.llvm.org/docs/LanguageExtensions.html
@ -132,8 +133,7 @@
/// ///
/// @param MAX Maximum value of the narrowest type of operand. /// @param MAX Maximum value of the narrowest type of operand.
/// Not used if compiler supports __builtin_add_overflow. /// Not used if compiler supports __builtin_add_overflow.
#if (defined(__clang__) && __has_builtin(__builtin_add_overflow)) \ #if HAVE_BUILTIN_ADD_OVERFLOW
|| (__GNUC__ >= 5)
# define STRICT_ADD(a, b, c, t) \ # define STRICT_ADD(a, b, c, t) \
do { if (__builtin_add_overflow(a, b, c)) { abort(); } } while (0) do { if (__builtin_add_overflow(a, b, c)) { abort(); } } while (0)
#else #else
@ -141,8 +141,9 @@
do { *(c) = (t)(a + b); } while (0) do { *(c) = (t)(a + b); } while (0)
#endif #endif
#if (defined(__clang__) && __has_builtin(__builtin_sub_overflow)) \ /// @def STRICT_SUB
|| (__GNUC__ >= 5) /// @brief Subtracts (a - b) and stores result in `c`. Aborts on overflow.
#if HAVE_BUILTIN_ADD_OVERFLOW
# define STRICT_SUB(a, b, c, t) \ # define STRICT_SUB(a, b, c, t) \
do { if (__builtin_sub_overflow(a, b, c)) { abort(); } } while (0) do { if (__builtin_sub_overflow(a, b, c)) { abort(); } } while (0)
#else #else