From ccb206fc8942f3450708f2d0d6b459d54cf881f1 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Wed, 26 Jul 2017 01:51:44 -0700 Subject: [PATCH] Add FOLLY_HAS_BUILTIN and use it 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 | 6 ++++++ folly/Launder.h | 21 ++++----------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/folly/CPortability.h b/folly/CPortability.h index ca5070a0..8f8ac21d 100644 --- a/folly/CPortability.h +++ b/folly/CPortability.h @@ -45,6 +45,12 @@ # 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__) diff --git a/folly/Launder.h b/folly/Launder.h index 2f9c47b8..6a3b976d 100644 --- a/folly/Launder.h +++ b/folly/Launder.h @@ -16,44 +16,31 @@ #pragma once +#include #include 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 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; -- 2.34.1