[llvm] r336161 - [Support] Fix llvm::unique_function when building with GCC 4.9 by

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 2 18:18:21 PDT 2018


Author: chandlerc
Date: Mon Jul  2 18:18:21 2018
New Revision: 336161

URL: http://llvm.org/viewvc/llvm-project?rev=336161&view=rev
Log:
[Support] Fix llvm::unique_function when building with GCC 4.9 by
introducing llvm::trivially_{copy,move}_constructible type traits.

This uses a completely portable implementation of these traits provided
by Richard Smith. You can see it on compiler explorer in all its glory:

  https://godbolt.org/g/QEDZjW

I have transcribed it, clang-formatted it, added some comments, and made
the tests fit into a unittest file.

I have also switched llvm::unique_function over to use these new, much
more portable traits. =D

Hopefully this will fix the build bot breakage from my prior commit.

Added:
    llvm/trunk/unittests/Support/TypeTraitsTest.cpp
Modified:
    llvm/trunk/include/llvm/ADT/FunctionExtras.h
    llvm/trunk/include/llvm/Support/type_traits.h
    llvm/trunk/unittests/Support/CMakeLists.txt

Modified: llvm/trunk/include/llvm/ADT/FunctionExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/FunctionExtras.h?rev=336161&r1=336160&r2=336161&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/FunctionExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/FunctionExtras.h Mon Jul  2 18:18:21 2018
@@ -35,8 +35,8 @@
 
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/type_traits.h"
 #include <memory>
-#include <type_traits>
 
 namespace llvm {
 
@@ -58,8 +58,8 @@ class unique_function<ReturnT(ParamTs...
   template <typename T>
   using AdjustedParamT = typename std::conditional<
       !std::is_reference<T>::value &&
-          std::is_trivially_copy_constructible<T>::value &&
-          std::is_trivially_move_constructible<T>::value &&
+          llvm::is_trivially_copy_constructible<T>::value &&
+          llvm::is_trivially_move_constructible<T>::value &&
           sizeof(T) <= (2 * sizeof(void *)),
       T, T &>::type;
 

Modified: llvm/trunk/include/llvm/Support/type_traits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/type_traits.h?rev=336161&r1=336160&r2=336161&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/type_traits.h (original)
+++ llvm/trunk/include/llvm/Support/type_traits.h Mon Jul  2 18:18:21 2018
@@ -104,6 +104,45 @@ struct const_pointer_or_const_ref<
   using type = typename add_const_past_pointer<T>::type;
 };
 
+namespace detail {
+/// Internal utility to detect trivial copy construction.
+template<typename T> union copy_construction_triviality_helper {
+    T t;
+    copy_construction_triviality_helper() = default;
+    copy_construction_triviality_helper(const copy_construction_triviality_helper&) = default;
+    ~copy_construction_triviality_helper() = default;
+};
+/// Internal utility to detect trivial move construction.
+template<typename T> union move_construction_triviality_helper {
+    T t;
+    move_construction_triviality_helper() = default;
+    move_construction_triviality_helper(move_construction_triviality_helper&&) = default;
+    ~move_construction_triviality_helper() = default;
+};
+} // end namespace detail
+
+/// An implementation of `std::is_trivially_copy_constructible` since we have
+/// users with STLs that don't yet include it.
+template <typename T>
+struct is_trivially_copy_constructible
+    : std::is_copy_constructible<
+          ::llvm::detail::copy_construction_triviality_helper<T>> {};
+template <typename T>
+struct is_trivially_copy_constructible<T &> : std::true_type {};
+template <typename T>
+struct is_trivially_copy_constructible<T &&> : std::false_type {};
+
+/// An implementation of `std::is_trivially_move_constructible` since we have
+/// users with STLs that don't yet include it.
+template <typename T>
+struct is_trivially_move_constructible
+    : std::is_move_constructible<
+          ::llvm::detail::move_construction_triviality_helper<T>> {};
+template <typename T>
+struct is_trivially_move_constructible<T &> : std::true_type {};
+template <typename T>
+struct is_trivially_move_constructible<T &&> : std::true_type {};
+
 } // end namespace llvm
 
 // If the compiler supports detecting whether a class is final, define

Modified: llvm/trunk/unittests/Support/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=336161&r1=336160&r2=336161&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Support/CMakeLists.txt Mon Jul  2 18:18:21 2018
@@ -59,6 +59,7 @@ add_llvm_unittest(SupportTests
   Threading.cpp
   TimerTest.cpp
   TypeNameTest.cpp
+  TypeTraitsTest.cpp
   TrailingObjectsTest.cpp
   TrigramIndexTest.cpp
   UnicodeTest.cpp

Added: llvm/trunk/unittests/Support/TypeTraitsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/TypeTraitsTest.cpp?rev=336161&view=auto
==============================================================================
--- llvm/trunk/unittests/Support/TypeTraitsTest.cpp (added)
+++ llvm/trunk/unittests/Support/TypeTraitsTest.cpp Mon Jul  2 18:18:21 2018
@@ -0,0 +1,77 @@
+//===- TypeTraitsTest.cpp -------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/type_traits.h"
+
+namespace {
+
+// Compile-time tests using static assert.
+namespace triviality {
+
+// Helper for compile time checking trivially copy constructible and trivially
+// move constructible type traits.
+template <typename T, bool IsTriviallyCopyConstructible,
+          bool IsTriviallyMoveConstructible>
+void TrivialityTester() {
+  static_assert(llvm::is_trivially_copy_constructible<T>::value ==
+                    IsTriviallyCopyConstructible,
+                "Mismatch in expected trivial copy construction!");
+  static_assert(llvm::is_trivially_move_constructible<T>::value ==
+                    IsTriviallyMoveConstructible,
+                "Mismatch in expected trivial move construction!");
+
+#if __clang__ || _MSC_VER || __GNUC__ > 5
+  // On compilers with support for the standard traits, make sure they agree.
+  static_assert(std::is_trivially_copy_constructible<T>::value ==
+                    IsTriviallyCopyConstructible,
+                "Mismatch in expected trivial copy construction!");
+  static_assert(std::is_trivially_move_constructible<T>::value ==
+                    IsTriviallyMoveConstructible,
+                "Mismatch in expected trivial move construction!");
+#endif
+};
+
+template void TrivialityTester<int, true, true>();
+template void TrivialityTester<void *, true, true>();
+template void TrivialityTester<int &, true, true>();
+template void TrivialityTester<int &&, false, true>();
+
+struct X {};
+struct Y {
+  Y(const Y &);
+};
+struct Z {
+  Z(const Z &);
+  Z(Z &&);
+};
+struct A {
+  A(const A &) = default;
+  A(A &&);
+};
+struct B {
+  B(const B &);
+  B(B &&) = default;
+};
+
+template void TrivialityTester<X, true, true>();
+template void TrivialityTester<Y, false, false>();
+template void TrivialityTester<Z, false, false>();
+template void TrivialityTester<A, true, false>();
+template void TrivialityTester<B, false, true>();
+
+template void TrivialityTester<Z &, true, true>();
+template void TrivialityTester<A &, true, true>();
+template void TrivialityTester<B &, true, true>();
+template void TrivialityTester<Z &&, false, true>();
+template void TrivialityTester<A &&, false, true>();
+template void TrivialityTester<B &&, false, true>();
+
+} // namespace triviality
+
+} // end anonymous namespace




More information about the llvm-commits mailing list