Skip to content

Commit

Permalink
Change the definition of is_trivially_relocatable to be a bit less co…
Browse files Browse the repository at this point in the history
…nservative.

Instead of ignoring __is_trivially_relocatable, use __is_trivially_relocatable && std::is_trivially_move_assignable.

PiperOrigin-RevId: 709106861
Change-Id: I2d53bd440133ad17bb676e53ee6a17d420a565d1
  • Loading branch information
ezbr authored and copybara-github committed Dec 23, 2024
1 parent 90a7ba6 commit 4198d9a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
16 changes: 13 additions & 3 deletions absl/meta/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,11 @@ using swap_internal::Swap;
// remove the condition.
//
// Clang on all platforms fails to detect that a type with a user-provided
// move-assignment operator is not trivially relocatable. So in fact we
// opt out of Clang altogether, for now.
// move-assignment operator is not trivially relocatable so we also check for
// is_trivially_move_assignable for Clang.
//
// TODO(b/325479096): Remove the opt-out once Clang's behavior is fixed.
// TODO(b/325479096): Remove the Clang is_trivially_move_assignable version once
// Clang's behavior is fixed.
//
// According to https://github.com/abseil/abseil-cpp/issues/1479, this does not
// work with NVCC either.
Expand All @@ -516,6 +517,15 @@ using swap_internal::Swap;
template <class T>
struct is_trivially_relocatable
: std::integral_constant<bool, __is_trivially_relocatable(T)> {};
#elif ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
!(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
!defined(__NVCC__)
template <class T>
struct is_trivially_relocatable
: std::integral_constant<
bool, std::is_trivially_copyable<T>::value ||
(__is_trivially_relocatable(T) &&
std::is_trivially_move_assignable<T>::value)> {};
#else
// Otherwise we use a fallback that detects only those types we can feasibly
// detect. Any type that is trivially copyable is by definition trivially
Expand Down
26 changes: 24 additions & 2 deletions absl/meta/type_traits_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,8 @@ TEST(TriviallyRelocatable, UserProvidedDestructor) {
// __is_trivially_relocatable is used there again.
// TODO(b/324278148): remove the opt-out for Apple once
// __is_trivially_relocatable is fixed there.
// TODO(b/325479096): remove the opt-out for Clang once
// __is_trivially_relocatable is fixed there.
#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \
ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \
(defined(__cpp_impl_trivially_relocatable) || \
Expand All @@ -779,8 +781,28 @@ TEST(TriviallyRelocatable, TrivialAbi) {
struct ABSL_ATTRIBUTE_TRIVIAL_ABI S {
S(S&&) {} // NOLINT(modernize-use-equals-default)
S(const S&) {} // NOLINT(modernize-use-equals-default)
void operator=(S&&) {}
void operator=(const S&) {}
S& operator=(S&&) { return *this; }
S& operator=(const S&) { return *this; }
~S() {} // NOLINT(modernize-use-equals-default)
};

static_assert(absl::is_trivially_relocatable<S>::value, "");
}
#endif

// TODO(b/275003464): remove the opt-out for Clang on Windows once
// __is_trivially_relocatable is used there again.
// TODO(b/324278148): remove the opt-out for Apple once
// __is_trivially_relocatable is fixed there.
#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \
ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
!(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
!defined(__NVCC__)
// A type marked with the "trivial ABI" attribute is trivially relocatable even
// if it has a user-provided copy constructor and a user-provided destructor.
TEST(TriviallyRelocatable, TrivialAbi_NoUserProvidedMove) {
struct ABSL_ATTRIBUTE_TRIVIAL_ABI S {
S(const S&) {} // NOLINT(modernize-use-equals-default)
~S() {} // NOLINT(modernize-use-equals-default)
};

Expand Down

0 comments on commit 4198d9a

Please sign in to comment.