X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FPortability.h;h=6c140379de9e9920755e3eb70cb615c6bd8acb88;hp=07426f0533a3456a15f5659fc15cca6afad7c0a2;hb=614eb71734a284e1a9fefabcc48743a3c8efd653;hpb=a595dcb51fd3f23343f6e11438f887f72df1ef31 diff --git a/folly/Portability.h b/folly/Portability.h index 07426f05..6c140379 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -31,7 +32,74 @@ constexpr bool kHasUnalignedAccess = true; #else constexpr bool kHasUnalignedAccess = false; #endif -} + +namespace portability_detail { + +template +using integral_max = std::integral_constant; + +template +struct integral_sequence_max + : integral_max::value> {}; + +template +struct integral_sequence_max : std::integral_constant {}; + +template +using max_alignment = integral_sequence_max; + +using max_basic_alignment = max_alignment< + std::max_align_t, + long double, + double, + float, + long long int, + long int, + int, + short int, + bool, + char, + char16_t, + char32_t, + wchar_t, + std::nullptr_t>; +} // namespace portability_detail + +constexpr size_t max_align_v = portability_detail::max_basic_alignment::value; + +// max_align_t is a type which is aligned at least as strictly as the +// most-aligned basic type (see the specification of std::max_align_t). This +// implementation exists because 32-bit iOS platforms have a broken +// std::max_align_t (see below). +// +// You should refer to this as `::folly::max_align_t` in portable code, even if +// you have `using namespace folly;` because C11 defines a global namespace +// `max_align_t` type. +// +// To be certain, we consider every non-void fundamental type specified by the +// standard. On most platforms `long double` would be enough, but iOS 32-bit +// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned +// `long double`. +// +// So far we've covered locals and other non-allocated storage, but we also need +// confidence that allocated storage from `malloc`, `new`, etc will also be +// suitable for objects with this alignment reuirement. +// +// Apple document that their implementation of malloc will issue 16-byte +// granularity chunks for small allocations (large allocations are page-size +// granularity and page-aligned). We think that allocated storage will be +// suitable for these objects based on the following assumptions: +// +// 1. 16-byte granularity also means 16-byte aligned. +// 2. `new` and other allocators follow the `malloc` rules. +// +// We also have some anecdotal evidence: we don't see lots of misaligned-storage +// crashes on 32-bit iOS apps that use `double`. +// +// Apple's allocation reference: http://bit.ly/malloc-small +struct alignas(max_align_v) max_align_t {}; + +} // namespace folly // compiler specific attribute translation // msvc should come first, so if clang is in msvc mode it gets the right defines @@ -43,7 +111,7 @@ constexpr bool kHasUnalignedAccess = false; #else # error Cannot define FOLLY_ALIGNED on this platform #endif -#define FOLLY_ALIGNED_MAX FOLLY_ALIGNED(alignof(std::max_align_t)) +#define FOLLY_ALIGNED_MAX FOLLY_ALIGNED(::folly::max_align_v) // NOTE: this will only do checking in msvc with versions that support /analyze #if _MSC_VER @@ -52,7 +120,7 @@ constexpr bool kHasUnalignedAccess = false; # endif /* nolint */ # define _USE_ATTRIBUTES_FOR_SAL 1 -# include +# include // @manual # define FOLLY_PRINTF_FORMAT _Printf_format_string_ # define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/ #else @@ -71,12 +139,19 @@ constexpr bool kHasUnalignedAccess = false; #endif // warn unused result +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(nodiscard) +#define FOLLY_NODISCARD [[nodiscard]] +#endif +#endif +#if !defined FOLLY_NODISCARD #if defined(_MSC_VER) && (_MSC_VER >= 1700) -#define FOLLY_WARN_UNUSED_RESULT _Check_return_ +#define FOLLY_NODISCARD _Check_return_ #elif defined(__clang__) || defined(__GNUC__) -#define FOLLY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) +#define FOLLY_NODISCARD __attribute__((__warn_unused_result__)) #else -#define FOLLY_WARN_UNUSED_RESULT +#define FOLLY_NODISCARD +#endif #endif // target @@ -94,9 +169,9 @@ constexpr bool kHasUnalignedAccess = false; #endif #if defined(__aarch64__) -# define FOLLY_A64 1 +# define FOLLY_AARCH64 1 #else -# define FOLLY_A64 0 +# define FOLLY_AARCH64 0 #endif #if defined (__powerpc64__) @@ -107,9 +182,30 @@ constexpr bool kHasUnalignedAccess = false; namespace folly { constexpr bool kIsArchAmd64 = FOLLY_X64 == 1; -constexpr bool kIsArchAArch64 = FOLLY_A64 == 1; +constexpr bool kIsArchAArch64 = FOLLY_AARCH64 == 1; constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1; -} +} // namespace folly + +namespace folly { + +#if FOLLY_SANITIZE_ADDRESS +constexpr bool kIsSanitizeAddress = true; +#else +constexpr bool kIsSanitizeAddress = false; +#endif + +#if FOLLY_SANITIZE_THREAD +constexpr bool kIsSanitizeThread = true; +#else +constexpr bool kIsSanitizeThread = false; +#endif + +#if FOLLY_SANITIZE +constexpr bool kIsSanitize = true; +#else +constexpr bool kIsSanitize = false; +#endif +} // namespace folly // packing is very ugly in msvc #ifdef _MSC_VER @@ -136,12 +232,10 @@ constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1; #elif defined(__clang__) || defined(__GNUC__) # define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push") # define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop") -#define FOLLY_GCC_DISABLE_WARNING_INTERNAL3(warningName) #warningName -#define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) \ - FOLLY_GCC_DISABLE_WARNING_INTERNAL3(warningName) -#define FOLLY_GCC_DISABLE_WARNING(warningName) \ - _Pragma(FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored \ - FOLLY_GCC_DISABLE_WARNING_INTERNAL3(-W##warningName))) +# define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) #warningName +# define FOLLY_GCC_DISABLE_WARNING(warningName) \ + _Pragma( \ + FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName)) // Disable the MSVC warnings. # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) #else @@ -151,33 +245,14 @@ constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1; # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) #endif -#ifdef HAVE_SHADOW_LOCAL_WARNINGS +#ifdef FOLLY_HAVE_SHADOW_LOCAL_WARNINGS #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS \ - FOLLY_GCC_DISABLE_WARNING(shadow-compatible-local) \ - FOLLY_GCC_DISABLE_WARNING(shadow-local) + FOLLY_GCC_DISABLE_WARNING("-Wshadow-compatible-local") \ + FOLLY_GCC_DISABLE_WARNING("-Wshadow-local") #else #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */ #endif -#if defined(__GNUC__) && !defined(__APPLE__) && !__GNUC_PREREQ(4,9) -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019 -// gcc 4.8.x incorrectly placed max_align_t in the root namespace -// Alias it into std (where it's found in 4.9 and later) -namespace std { typedef ::max_align_t max_align_t; } -#endif - -// portable version check for clang -#ifndef __CLANG_PREREQ -# if defined __clang__ && defined __clang_major__ && defined __clang_minor__ -/* nolint */ -# define __CLANG_PREREQ(maj, min) \ - ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min)) -# else -/* nolint */ -# define __CLANG_PREREQ(maj, min) 0 -# endif -#endif - /* Platform specific TLS support * gcc implements __thread * msvc implements __declspec(thread) @@ -200,7 +275,7 @@ namespace std { typedef ::max_align_t max_align_t; } // the 'std' namespace; the latter uses inline namespaces. Wrap this decision // up in a macro to make forward-declarations easier. #if FOLLY_USE_LIBCPP -#include <__config> +#include <__config> // @manual #define FOLLY_NAMESPACE_STD_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD #define FOLLY_NAMESPACE_STD_END _LIBCPP_END_NAMESPACE_STD #else @@ -244,7 +319,7 @@ constexpr auto kIsDebug = false; #else constexpr auto kIsDebug = true; #endif -} +} // namespace folly // Endianness namespace folly { @@ -259,7 +334,7 @@ constexpr auto kIsLittleEndian = true; constexpr auto kIsLittleEndian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; #endif constexpr auto kIsBigEndian = !kIsLittleEndian; -} +} // namespace folly #ifndef FOLLY_SSE # if defined(__SSE4_2__) @@ -293,12 +368,12 @@ constexpr auto kIsBigEndian = !kIsLittleEndian; namespace FOLLY_GFLAGS_NAMESPACE { } namespace gflags { using namespace FOLLY_GFLAGS_NAMESPACE; -} // namespace gflags +} // namespace gflags #endif // for TARGET_OS_IPHONE #ifdef __APPLE__ -#include +#include // @manual #endif // RTTI may not be enabled for this compilation unit. @@ -318,6 +393,12 @@ using namespace FOLLY_GFLAGS_NAMESPACE; namespace folly { +#if __OBJC__ +constexpr auto kIsObjC = true; +#else +constexpr auto kIsObjC = false; +#endif + #if defined(__linux__) && !FOLLY_MOBILE constexpr auto kIsLinux = true; #else @@ -326,7 +407,36 @@ constexpr auto kIsLinux = false; #if defined(_WIN32) constexpr auto kIsWindows = true; +constexpr auto kMscVer = _MSC_VER; #else constexpr auto kIsWindows = false; +constexpr auto kMscVer = 0; +#endif +} // namespace folly + +// Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14 +// constexpr support is "good enough". +#ifndef FOLLY_USE_CPP14_CONSTEXPR +#if defined(__clang__) +#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L +#elif defined(__GNUC__) +#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L +#else +#define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC? +#endif +#endif + +#if FOLLY_USE_CPP14_CONSTEXPR +#define FOLLY_CPP14_CONSTEXPR constexpr +#else +#define FOLLY_CPP14_CONSTEXPR inline +#endif + +#if __cpp_coroutines >= 201703L || (_MSC_VER && _RESUMABLE_FUNCTIONS_SUPPORTED) +#define FOLLY_HAS_COROUTINES 1 +#endif + +// MSVC 2017.5 +#if __cpp_noexcept_function_type >= 201510 || _MSC_FULL_VER >= 191225816 +#define FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE 1 #endif -}