[llvm] r341865 - [ADT] bit_cast: check for is_trivially_copyable more portably

JF Bastien via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 10 14:33:45 PDT 2018


Author: jfb
Date: Mon Sep 10 14:33:45 2018
New Revision: 341865

URL: http://llvm.org/viewvc/llvm-project?rev=341865&view=rev
Log:
[ADT] bit_cast: check for is_trivially_copyable more portably

Summary:
It turns out that isPodLike isn't a good workaround for is_trivially_copyable for bit_cast's purpose. In D51872 Louis points out that tuple and pair really aren't a good fit, and for bit_cast I want to capture array. This patch instead checks is_trivially_copyable directly in bit_cast for all but GCC 4.x. In GCC 4.x developers only check for sizeof match, which means any mistake they make will succeed locally and fail on the bots. Realistically that's few developers and they'll be left behind once we upgrade past C++11.

This will allow using bit_cast with std::array.

Subscribers: dexonsmith, llvm-commits, ldionne, rsmith

Differential Revision: https://reviews.llvm.org/D51888

Modified:
    llvm/trunk/include/llvm/ADT/bit.h

Modified: llvm/trunk/include/llvm/ADT/bit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/bit.h?rev=341865&r1=341864&r2=341865&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/bit.h (original)
+++ llvm/trunk/include/llvm/ADT/bit.h Mon Sep 10 14:33:45 2018
@@ -14,15 +14,29 @@
 #ifndef LLVM_ADT_BIT_H
 #define LLVM_ADT_BIT_H
 
-#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Compiler.h"
 #include <cstring>
+#include <type_traits>
 
 namespace llvm {
 
-template <typename To, typename From,
-          typename = typename std::enable_if<sizeof(To) == sizeof(From)>::type,
-          typename = typename std::enable_if<isPodLike<To>::value>::type,
-          typename = typename std::enable_if<isPodLike<From>::value>::type>
+template <typename To, typename From
+          , typename = typename std::enable_if<sizeof(To) == sizeof(From)>::type
+#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \
+    (defined(__GNUC__) && __GNUC__ >= 5)
+          , typename = typename std::enable_if<std::is_trivially_copyable<To>::value>::type
+          , typename = typename std::enable_if<std::is_trivially_copyable<From>::value>::type
+#elif __has_feature(is_trivially_copyable)
+          , typename = typename std::enable_if<__is_trivially_copyable<To>::value>::type
+          , typename = typename std::enable_if<__is_trivially_copyable<From>::value>::type
+#else
+  // This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike
+  // llvm/Support/type_traits.h's isPodLike we don't want to provide a
+  // good-enough answer here: developers in that configuration will hit
+  // compilation failures on the bots instead of locally. That's acceptable
+  // because it's very few developers, and only until we move past C++11.
+#endif
+>
 inline To bit_cast(const From &from) noexcept {
   alignas(To) unsigned char storage[sizeof(To)];
   std::memcpy(&storage, &from, sizeof(To));




More information about the llvm-commits mailing list