Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -325,6 +325,14 @@ unset(HAVE_FFI_CALL CACHE) endif( LLVM_ENABLE_FFI ) +check_cxx_source_compiles(" +#include +struct some_type {}; +static_assert(std::is_trivially_copyable::value, \"ok\"); +int main() { return 0;}" +HAVE_STD_IS_TRIVIALLY_COPYABLE) + + # Define LLVM_HAS_ATOMICS if gcc or MSVC atomic builtins are supported. include(CheckAtomic) Index: include/llvm/Config/config.h.cmake =================================================================== --- include/llvm/Config/config.h.cmake +++ include/llvm/Config/config.h.cmake @@ -338,6 +338,9 @@ /* Define as the return type of signal handlers (`int' or `void'). */ #cmakedefine RETSIGTYPE ${RETSIGTYPE} +/* Define if std::is_trivially_copyable is supported */ +#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE ${HAVE_STD_IS_TRIVIALLY_COPYABLE} + /* Define to a function implementing stricmp */ #cmakedefine stricmp ${stricmp} Index: include/llvm/Support/type_traits.h =================================================================== --- include/llvm/Support/type_traits.h +++ include/llvm/Support/type_traits.h @@ -119,6 +119,15 @@ template struct is_trivially_move_constructible : std::true_type {}; +template +class is_copy_assignable { + template + static std::true_type apply(decltype(std::declval()=std::declval())*); + static std::false_type apply(...); + public: + static constexpr bool value = decltype(apply((T*)nullptr))::value; +}; + // An implementation of `std::is_trivially_copyable` since STL version // is not equally supported by all compilers, especially GCC 4.9. // Uniform implementation of this trait is important for ABI compatibility @@ -140,9 +149,9 @@ // copy assign static constexpr bool has_trivial_copy_assign = - std::is_copy_assignable>::value; + is_copy_assignable>::value; static constexpr bool has_deleted_copy_assign = - !std::is_copy_assignable::value; + !is_copy_assignable::value; // move assign static constexpr bool has_trivial_move_assign = @@ -163,8 +172,9 @@ (has_deleted_copy_assign || has_trivial_copy_assign) && (has_deleted_copy_constructor || has_trivial_copy_constructor); -#if (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)) - static_assert(value == std::is_trivially_copyable::value, "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); +#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE + static_assert(value == std::is_trivially_copyable::value, + "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); #endif };