diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h --- a/libc/src/__support/CPP/bit.h +++ b/libc/src/__support/CPP/bit.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_SUPPORT_CPP_BIT_H #define LLVM_LIBC_SUPPORT_CPP_BIT_H +#include "src/__support/CPP/type_traits.h" #include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN namespace __llvm_libc::cpp { @@ -25,9 +26,15 @@ // GCC >= 8 and Clang >= 6. template constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From), "To and From must be of same size"); + static_assert(cpp::is_trivially_copyable::value && + cpp::is_trivially_copyable::value, + "Cannot bit-cast instances of non-trivially copyable classes."); #if defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST) return __builtin_bit_cast(To, from); #else + static_assert(cpp::is_trivially_constructible::value, + "This implementation additionally requires destination type to " + "be trivially constructible"); To to; char *dst = reinterpret_cast(&to); const char *src = reinterpret_cast(&from); diff --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h --- a/libc/src/__support/CPP/type_traits.h +++ b/libc/src/__support/CPP/type_traits.h @@ -12,9 +12,7 @@ namespace __llvm_libc { namespace cpp { -template struct type_identity { - using type = T; -}; +template struct type_identity { using type = T; }; template struct enable_if; template struct enable_if : type_identity {}; @@ -28,6 +26,14 @@ using true_type = cpp::integral_constant; using false_type = cpp::integral_constant; +template +struct is_trivially_copyable + : public integral_constant {}; + +template +struct is_trivially_constructible + : integral_constant {}; + template struct is_same : cpp::false_type {}; template struct is_same : cpp::true_type {}; template