bpo-41617: Add _Py__has_builtin() macro (GH-23260)

Fix building pycore_bitutils.h internal header on old clang version
without __builtin_bswap16() (ex: Xcode 4.6.3 on Mac OS X 10.7).

Add a new private _Py__has_builtin() macro to check for availability
of a preprocessor builtin function.

Co-Authored-By: Joshua Root <jmr@macports.org>

Co-authored-by: Joshua Root <jmr@macports.org>
This commit is contained in:
Victor Stinner 2020-11-13 15:38:17 +01:00 committed by GitHub
parent d96a7a8313
commit b3b98082c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 9 deletions

View File

@ -17,12 +17,9 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
#if ((defined(__GNUC__) \ #if defined(__GNUC__) \
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) \ && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
|| (defined(__clang__) \ /* __builtin_bswap16() is available since GCC 4.8,
&& (__clang_major__ >= 4 \
|| (__clang_major__ == 3 && __clang_minor__ >= 2))))
/* __builtin_bswap16() is available since GCC 4.8 and clang 3.2,
__builtin_bswap32() is available since GCC 4.3, __builtin_bswap32() is available since GCC 4.3,
__builtin_bswap64() is available since GCC 4.3. */ __builtin_bswap64() is available since GCC 4.3. */
# define _PY_HAVE_BUILTIN_BSWAP # define _PY_HAVE_BUILTIN_BSWAP
@ -36,7 +33,7 @@ extern "C" {
static inline uint16_t static inline uint16_t
_Py_bswap16(uint16_t word) _Py_bswap16(uint16_t word)
{ {
#ifdef _PY_HAVE_BUILTIN_BSWAP #if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16)
return __builtin_bswap16(word); return __builtin_bswap16(word);
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short)); Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short));
@ -51,7 +48,7 @@ _Py_bswap16(uint16_t word)
static inline uint32_t static inline uint32_t
_Py_bswap32(uint32_t word) _Py_bswap32(uint32_t word)
{ {
#ifdef _PY_HAVE_BUILTIN_BSWAP #if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32)
return __builtin_bswap32(word); return __builtin_bswap32(word);
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long)); Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long));
@ -68,7 +65,7 @@ _Py_bswap32(uint32_t word)
static inline uint64_t static inline uint64_t
_Py_bswap64(uint64_t word) _Py_bswap64(uint64_t word)
{ {
#ifdef _PY_HAVE_BUILTIN_BSWAP #if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64)
return __builtin_bswap64(word); return __builtin_bswap64(word);
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
return _byteswap_uint64(word); return _byteswap_uint64(word);

View File

@ -869,4 +869,16 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler;
# define _Py_NO_RETURN # define _Py_NO_RETURN
#endif #endif
// Preprocessor check for a builtin preprocessor function. Always return 0
// if __has_builtin() macro is not defined.
//
// __has_builtin() is available on clang and GCC 10.
#ifdef __has_builtin
# define _Py__has_builtin(x) __has_builtin(x)
#else
# define _Py__has_builtin(x) 0
#endif
#endif /* Py_PYPORT_H */ #endif /* Py_PYPORT_H */

View File

@ -0,0 +1,3 @@
Fix building ``pycore_bitutils.h`` internal header on old clang version
without ``__builtin_bswap16()`` (ex: Xcode 4.6.3 on Mac OS X 10.7). Patch by
Joshua Root and Victor Stinner.