diff --git a/Include/internal/pycore_bitutils.h b/Include/internal/pycore_bitutils.h index 0bd3270fe82e5c..aa2a489f13c1f5 100644 --- a/Include/internal/pycore_bitutils.h +++ b/Include/internal/pycore_bitutils.h @@ -17,9 +17,14 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#if defined(__clang__) || \ - (defined(__GNUC__) && \ - ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) +// Don't break compilers that don't know about __has_builtin +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +// No check for clang here, __has_builtin is used instead +#if defined(__GNUC__) && \ + ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) /* __builtin_bswap16() is available since GCC 4.8, __builtin_bswap32() is available since GCC 4.3, __builtin_bswap64() is available since GCC 4.3. */ @@ -34,7 +39,7 @@ extern "C" { static inline uint16_t _Py_bswap16(uint16_t word) { -#ifdef _PY_HAVE_BUILTIN_BSWAP +#if defined(_PY_HAVE_BUILTIN_BSWAP) || __has_builtin(__builtin_bswap16) return __builtin_bswap16(word); #elif defined(_MSC_VER) Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short)); @@ -49,7 +54,7 @@ _Py_bswap16(uint16_t word) static inline uint32_t _Py_bswap32(uint32_t word) { -#ifdef _PY_HAVE_BUILTIN_BSWAP +#if defined(_PY_HAVE_BUILTIN_BSWAP) || __has_builtin(__builtin_bswap32) return __builtin_bswap32(word); #elif defined(_MSC_VER) Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long)); @@ -66,7 +71,7 @@ _Py_bswap32(uint32_t word) static inline uint64_t _Py_bswap64(uint64_t word) { -#ifdef _PY_HAVE_BUILTIN_BSWAP +#if defined(_PY_HAVE_BUILTIN_BSWAP) || __has_builtin(__builtin_bswap64) return __builtin_bswap64(word); #elif defined(_MSC_VER) return _byteswap_uint64(word);