Add FOLLY_HAS_BUILTIN and use it
authorYedidya Feldblum <yfeldblum@fb.com>
Wed, 26 Jul 2017 08:51:44 +0000 (01:51 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 26 Jul 2017 09:06:56 +0000 (02:06 -0700)
Summary:
[Folly] Add `FOLLY_HAS_BUILTIN` and use it.

Use it in the definition of `folly::launder`. Of course, since GCC does not have `__has_builtin`, we still have to check its version.

Reviewed By: WillerZ

Differential Revision: D5496748

fbshipit-source-id: 3bd6e89424dfd2c9cb9795ee4d88f66c4294cc4c

folly/CPortability.h
folly/Launder.h

index ca5070a0f551991d6bf541c775aab7798f0458be..8f8ac21d6e63062ddcca40bf42715bc3df9f84f9 100644 (file)
 # endif
 #endif
 
+#if defined(__has_builtin)
+#define FOLLY_HAS_BUILTIN(...) __has_builtin(__VA_ARGS__)
+#else
+#define FOLLY_HAS_BUILTIN(...) 0
+#endif
+
 /* Define a convenience macro to test when address sanitizer is being used
  * across the different compilers (e.g. clang, gcc) */
 #if defined(__clang__)
index 2f9c47b8788e1aead9066186c9e9c349b83e9cbb..6a3b976dee649d7fadd38220370039f44c202752 100644 (file)
 
 #pragma once
 
+#include <folly/CPortability.h>
 #include <folly/Portability.h>
 
 namespace folly {
 
-#ifdef __GNUC__
-#ifdef __has_builtin
-#if __has_builtin(__builtin_launder)
-#define FOLLY_USE_BUILTIN_LAUNDER 1
-#endif
-#endif
-#endif
-
 /**
  * Approximate backport from C++17 of std::launder. It should be `constexpr`
  * but that can't be done without specific support from the compiler.
  */
 template <typename T>
 FOLLY_NODISCARD inline T* launder(T* in) noexcept {
-#ifdef __GNUC__
-#ifdef FOLLY_USE_BUILTIN_LAUNDER
-  // Newer GCC versions have a builtin for this with no unwanted side-effects
+#if FOLLY_HAS_BUILTIN(__builtin_launder) || __GNUC__ >= 7
+  // The builtin has no unwanted side-effects.
   return __builtin_launder(in);
-#else
+#elif __GNUC__
   // This inline assembler block declares that `in` is an input and an output,
   // so the compiler has to assume that it has been changed inside the block.
   __asm__("" : "+r"(in));
   return in;
-#endif
 #else
   static_assert(
       false, "folly::launder is not implemented for this environment");
 #endif
 }
 
-#ifdef FOLLY_USE_BUILTIN_LAUNDER
-#undef FOLLY_USE_BUILTIN_LAUNDER
-#endif
-
 /* The standard explicitly forbids laundering these */
 void launder(void*) = delete;
 void launder(void const*) = delete;