瀏覽代碼

Correctly check for bswap builtins before using

The __clang_major__ and __clang_minor__ macros provide a marketing
version, which is not necessarily comparable for clang distributions
from different vendors[1]. In practice, the versioning scheme for
Apple's clang is indeed completely different to that of the llvm.org
releases. It is thus preferable to check for features directly rather
than comparing versions.

In this specific case, __builtin_bswap16 was being used with older
Apple clang versions that don't support it.

[1] https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros
Joshua Root 4 年之前
父節點
當前提交
9bf6557585
共有 2 個文件被更改,包括 14 次插入3 次删除
  1. 3 3
      include/SDL_endian.h
  2. 11 0
      include/SDL_stdinc.h

+ 3 - 3
include/SDL_endian.h

@@ -91,7 +91,7 @@ extern "C" {
 /**
  *  \file SDL_endian.h
  */
-#if (defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2))) || \
+#if (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \
     (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
 #define SDL_Swap16(x) __builtin_bswap16(x)
 #elif defined(__GNUC__) && defined(__i386__) && \
@@ -149,7 +149,7 @@ SDL_Swap16(Uint16 x)
 }
 #endif
 
-#if (defined(__clang__) && (__clang_major__ > 2 || (__clang_major__ == 2 && __clang_minor__ >= 6))) || \
+#if (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \
     (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
 #define SDL_Swap32(x) __builtin_bswap32(x)
 #elif defined(__GNUC__) && defined(__i386__) && \
@@ -210,7 +210,7 @@ SDL_Swap32(Uint32 x)
 }
 #endif
 
-#if (defined(__clang__) && (__clang_major__ > 2 || (__clang_major__ == 2 && __clang_minor__ >= 6))) || \
+#if (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \
     (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
 #define SDL_Swap64(x) __builtin_bswap64(x)
 #elif defined(__GNUC__) && defined(__i386__) && \

+ 11 - 0
include/SDL_stdinc.h

@@ -115,6 +115,17 @@ char *alloca();
 # endif
 #endif
 
+/**
+ * Check if the compiler supports a given builtin.
+ * Supported by virtually all clang versions and recent gcc. Use this
+ * instead of checking the clang version if possible.
+ */
+#ifdef __has_builtin
+#define _SDL_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#define _SDL_HAS_BUILTIN(x) 0
+#endif
+
 /**
  *  The number of elements in an array.
  */