llvm.org GIT mirror llvm / 469bae0
[ADT] restrict bit_cast to trivially-constructible To Summary: As discussed in r341853 by blaikie, the reinterpret_cast was technically an aliasing violation. Restrict our bit_cast implementation to To which are trivially-constructible (and note the existing restriction to constexpr). Once we move to C++17 we can use a version of bit_cast without these restrictions, or if we care we can SFINAE a different implementation when To isn't trivially-constructible. Reviewers: dblaikie, rsmith Subscribers: dexonsmith, kristina, llvm-commits Differential Revision: https://reviews.llvm.org/D52332 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342710 91177308-0d34-0410-b5e6-96231b3b80d8 JF Bastien 1 year, 10 months ago
1 changed file(s) with 7 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
1919
2020 namespace llvm {
2121
22 // This implementation of bit_cast is different from the C++17 one in two ways:
23 // - It isn't constexpr because that requires compiler support.
24 // - It requires trivially-constructible To, to avoid UB in the implementation.
2225 template
2326 , typename = typename std::enable_if::type
27 , typename = typename std::is_trivially_constructible::type
2428 #if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \
2529 (defined(__GNUC__) && __GNUC__ >= 5)
2630 , typename = typename std::enable_if::value>::type
3741 #endif
3842 >
3943 inline To bit_cast(const From &from) noexcept {
40 alignas(To) unsigned char storage[sizeof(To)];
41 std::memcpy(&storage, &from, sizeof(To));
42 #if defined(__GNUC__)
43 // Before GCC 7.2, GCC thought that this violated strict aliasing.
44 #pragma GCC diagnostic push
45 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
46 #endif
47 return reinterpret_cast(storage);
48 #if defined(__GNUC__)
49 #pragma GCC diagnostic pop
50 #endif
44 To to;
45 std::memcpy(&to, &from, sizeof(To));
46 return to;
5147 }
5248
5349 } // namespace llvm