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 { @@ -26,8 +27,10 @@ template constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From), "To and From must be of same size"); #if defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST) - return __builtin_bit_cast(To, from); -#else + if constexpr (cpp::is_trivially_copyable::value && + cpp::is_trivially_copyable::value) + return __builtin_bit_cast(To, from); +#endif // defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST) To to; char *dst = reinterpret_cast(&to); const char *src = reinterpret_cast(&from); @@ -38,7 +41,6 @@ dst[i] = src[i]; #endif // defined(LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE) return to; -#endif // defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST) } } // namespace __llvm_libc::cpp 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 @@ -28,6 +28,10 @@ using true_type = cpp::integral_constant; using false_type = cpp::integral_constant; +template +struct is_trivially_copyable + : public integral_constant {}; + template struct is_same : cpp::false_type {}; template struct is_same : cpp::true_type {}; template