[llvm] r351820 - Fix llvm::is_trivially_copyable portability issues
Serge Guelton via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 22 05:48:56 PST 2019
Author: serge_sans_paille
Date: Tue Jan 22 05:48:55 2019
New Revision: 351820
URL: http://llvm.org/viewvc/llvm-project?rev=351820&view=rev
Log:
Fix llvm::is_trivially_copyable portability issues
llvm::is_trivially_copyable portability is verified at compile time using
std::is_trivially_copyable as the reference implementation.
Unfortunately, the latter is not available on all platforms, so introduce
a proper configure check to detect if it is available on the target platform.
In a similar manner, std::is_copy_assignable is not fully supported for gcc4.9.
Provide a portable (?) implementation instead.
Differential Revision: https://reviews.llvm.org/D57018
Modified:
llvm/trunk/cmake/config-ix.cmake
llvm/trunk/include/llvm/ADT/PointerIntPair.h
llvm/trunk/include/llvm/Config/config.h.cmake
llvm/trunk/include/llvm/Support/type_traits.h
Modified: llvm/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=351820&r1=351819&r2=351820&view=diff
==============================================================================
--- llvm/trunk/cmake/config-ix.cmake (original)
+++ llvm/trunk/cmake/config-ix.cmake Tue Jan 22 05:48:55 2019
@@ -325,6 +325,15 @@ else()
unset(HAVE_FFI_CALL CACHE)
endif( LLVM_ENABLE_FFI )
+# Whether we can use std::is_trivially_copyable to verify llvm::is_trivially_copyable.
+CHECK_CXX_SOURCE_COMPILES("
+#include <type_traits>
+struct T { int val; };
+static_assert(std::is_trivially_copyable<T>::value, \"ok\");
+int main() { return 0;}
+" HAVE_STD_IS_TRIVIALLY_COPYABLE)
+
+
# Define LLVM_HAS_ATOMICS if gcc or MSVC atomic builtins are supported.
include(CheckAtomic)
Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=351820&r1=351819&r2=351820&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original)
+++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Tue Jan 22 05:48:55 2019
@@ -14,6 +14,7 @@
#define LLVM_ADT_POINTERINTPAIR_H
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstdint>
#include <limits>
@@ -125,6 +126,19 @@ public:
}
};
+// Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable
+// when compiled with gcc 4.9.
+template <typename PointerTy, unsigned IntBits, typename IntType,
+ typename PtrTraits,
+ typename Info>
+struct is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> : std::true_type {
+#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+ static_assert(std::is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>::value,
+ "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+#endif
+};
+
+
template <typename PointerT, unsigned IntBits, typename PtrTraits>
struct PointerIntPairInfo {
static_assert(PtrTraits::NumLowBitsAvailable <
Modified: llvm/trunk/include/llvm/Config/config.h.cmake
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=351820&r1=351819&r2=351820&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Config/config.h.cmake (original)
+++ llvm/trunk/include/llvm/Config/config.h.cmake Tue Jan 22 05:48:55 2019
@@ -338,6 +338,9 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#cmakedefine RETSIGTYPE ${RETSIGTYPE}
+/* Define if std::is_trivially_copyable is supported */
+#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE ${HAVE_STD_IS_TRIVIALLY_COPYABLE}
+
/* Define to a function implementing stricmp */
#cmakedefine stricmp ${stricmp}
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=351820&r1=351819&r2=351820&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/type_traits.h (original)
+++ llvm/trunk/include/llvm/Support/type_traits.h Tue Jan 22 05:48:55 2019
@@ -95,6 +95,7 @@ template<class T>
union trivial_helper {
T t;
};
+
} // end namespace detail
/// An implementation of `std::is_trivially_copy_constructible` since we have
@@ -119,6 +120,24 @@ struct is_trivially_move_constructible<T
template <typename T>
struct is_trivially_move_constructible<T &&> : std::true_type {};
+
+template <typename T>
+struct is_copy_assignable {
+ template<class F>
+ static auto get(F*) -> decltype(std::declval<T &>() = std::declval<const T &>(), std::true_type{});
+ static std::false_type get(...);
+ static constexpr bool value = decltype(get((T*)nullptr))::value;
+};
+
+template <typename T>
+struct is_move_assignable {
+ template<class F>
+ static auto get(F*) -> decltype(std::declval<T &>() = std::declval<T &&>(), std::true_type{});
+ static std::false_type get(...);
+ static constexpr bool value = decltype(get((T*)nullptr))::value;
+};
+
+
// An implementation of `std::is_trivially_copyable` since STL version
// is not equally supported by all compilers, especially GCC 4.9.
// Uniform implementation of this trait is important for ABI compatibility
@@ -140,15 +159,15 @@ class is_trivially_copyable {
// copy assign
static constexpr bool has_trivial_copy_assign =
- std::is_copy_assignable<detail::trivial_helper<T>>::value;
+ is_copy_assignable<detail::trivial_helper<T>>::value;
static constexpr bool has_deleted_copy_assign =
- !std::is_copy_assignable<T>::value;
+ !is_copy_assignable<T>::value;
// move assign
static constexpr bool has_trivial_move_assign =
- std::is_move_assignable<detail::trivial_helper<T>>::value;
+ is_move_assignable<detail::trivial_helper<T>>::value;
static constexpr bool has_deleted_move_assign =
- !std::is_move_assignable<T>::value;
+ !is_move_assignable<T>::value;
// destructor
static constexpr bool has_trivial_destructor =
@@ -163,10 +182,14 @@ class is_trivially_copyable {
(has_deleted_copy_assign || has_trivial_copy_assign) &&
(has_deleted_copy_constructor || has_trivial_copy_constructor);
-#if (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5))
- static_assert(value == std::is_trivially_copyable<T>::value, "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+ static_assert(value == std::is_trivially_copyable<T>::value,
+ "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
#endif
};
+template <typename T>
+class is_trivially_copyable<T*> : public std::true_type {
+};
} // end namespace llvm
More information about the llvm-commits
mailing list