mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-02 02:14:23 +00:00
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 llvm-svn: 351820
This commit is contained in:
parent
af41a20065
commit
1e000b2c69
@ -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)
|
||||
|
||||
|
@ -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 <
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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 &> : std::true_type {};
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user