Skip to content

Commit a4950fb

Browse files
derekmaurocopybara-github
authored andcommitted
Use __builtin_is_cpp_trivially_relocatable to implement
absl::is_trivially_relocatable in a way that is compatible with PR2786 in the upcoming C++26. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2786r11.html This change is being made now because Chromium is reporting that a recent LLVM commit adds deprecation warnings for __is_trivially_relocatable. llvm/llvm-project#138835 PiperOrigin-RevId: 756408712 Change-Id: Iacf966ed2ebfd436d52d180f0dab34465b3c7176
1 parent db8171f commit a4950fb

File tree

2 files changed

+18
-54
lines changed

2 files changed

+18
-54
lines changed

absl/meta/type_traits.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,17 @@ using swap_internal::Swap;
324324

325325
// absl::is_trivially_relocatable<T>
326326
//
327+
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2786r11.html
328+
//
327329
// Detects whether a type is known to be "trivially relocatable" -- meaning it
328330
// can be relocated from one place to another as if by memcpy/memmove.
329331
// This implies that its object representation doesn't depend on its address,
330332
// and also none of its special member functions do anything strange.
331333
//
334+
// Note that when relocating the caller code should ensure that if the object is
335+
// polymorphic, the dynamic type is of the most derived type. Padding bytes
336+
// should not be copied.
337+
//
332338
// This trait is conservative. If it's true then the type is definitely
333339
// trivially relocatable, but if it's false then the type may or may not be. For
334340
// example, std::vector<int> is trivially relocatable on every known STL
@@ -346,11 +352,7 @@ using swap_internal::Swap;
346352
//
347353
// Upstream documentation:
348354
//
349-
// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable
350-
351-
// If the compiler offers a builtin that tells us the answer, we can use that.
352-
// This covers all of the cases in the fallback below, plus types that opt in
353-
// using e.g. [[clang::trivial_abi]].
355+
// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__builtin_is_cpp_trivially_relocatable
354356
//
355357
// Clang on Windows has the builtin, but it falsely claims types with a
356358
// user-provided destructor are trivial (http://b/275003464). So we opt out
@@ -375,15 +377,22 @@ using swap_internal::Swap;
375377
//
376378
// According to https://github.com/abseil/abseil-cpp/issues/1479, this does not
377379
// work with NVCC either.
378-
#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \
379-
(defined(__cpp_impl_trivially_relocatable) || \
380-
(!defined(__clang__) && !defined(__APPLE__) && !defined(__NVCC__)))
380+
#if ABSL_HAVE_BUILTIN(__builtin_is_cpp_trivially_relocatable)
381+
// https://github.com/llvm/llvm-project/pull/127636#pullrequestreview-2637005293
382+
// In the current implementation, __builtin_is_cpp_trivially_relocatable will
383+
// only return true for types that are trivially relocatable according to the
384+
// standard. Notably, this means that marking a type [[clang::trivial_abi]] aka
385+
// ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI will have no effect on this trait.
381386
template <class T>
382387
struct is_trivially_relocatable
383-
: std::integral_constant<bool, __is_trivially_relocatable(T)> {};
388+
: std::integral_constant<bool, __builtin_is_cpp_trivially_relocatable(T)> {
389+
};
384390
#elif ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
385391
!(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
386392
!defined(__NVCC__)
393+
// https://github.com/llvm/llvm-project/pull/139061
394+
// __is_trivially_relocatable is deprecated.
395+
// TODO(b/325479096): Remove this case.
387396
template <class T>
388397
struct is_trivially_relocatable
389398
: std::integral_constant<

absl/meta/type_traits_test.cc

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -333,51 +333,6 @@ TEST(TriviallyRelocatable, UserProvidedDestructor) {
333333
static_assert(!absl::is_trivially_relocatable<S>::value, "");
334334
}
335335

336-
// TODO(b/275003464): remove the opt-out for Clang on Windows once
337-
// __is_trivially_relocatable is used there again.
338-
// TODO(b/324278148): remove the opt-out for Apple once
339-
// __is_trivially_relocatable is fixed there.
340-
// TODO(b/325479096): remove the opt-out for Clang once
341-
// __is_trivially_relocatable is fixed there.
342-
#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \
343-
ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \
344-
(defined(__cpp_impl_trivially_relocatable) || \
345-
(!defined(__clang__) && !defined(__APPLE__) && !defined(__NVCC__)))
346-
// A type marked with the "trivial ABI" attribute is trivially relocatable even
347-
// if it has user-provided special members.
348-
TEST(TriviallyRelocatable, TrivialAbi) {
349-
struct ABSL_ATTRIBUTE_TRIVIAL_ABI S {
350-
S(S&&) {} // NOLINT(modernize-use-equals-default)
351-
S(const S&) {} // NOLINT(modernize-use-equals-default)
352-
S& operator=(S&&) { return *this; }
353-
S& operator=(const S&) { return *this; }
354-
~S() {} // NOLINT(modernize-use-equals-default)
355-
};
356-
357-
static_assert(absl::is_trivially_relocatable<S>::value, "");
358-
}
359-
#endif
360-
361-
// TODO(b/275003464): remove the opt-out for Clang on Windows once
362-
// __is_trivially_relocatable is used there again.
363-
// TODO(b/324278148): remove the opt-out for Apple once
364-
// __is_trivially_relocatable is fixed there.
365-
#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \
366-
ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
367-
!(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
368-
!defined(__NVCC__)
369-
// A type marked with the "trivial ABI" attribute is trivially relocatable even
370-
// if it has a user-provided copy constructor and a user-provided destructor.
371-
TEST(TriviallyRelocatable, TrivialAbi_NoUserProvidedMove) {
372-
struct ABSL_ATTRIBUTE_TRIVIAL_ABI S {
373-
S(const S&) {} // NOLINT(modernize-use-equals-default)
374-
~S() {} // NOLINT(modernize-use-equals-default)
375-
};
376-
377-
static_assert(absl::is_trivially_relocatable<S>::value, "");
378-
}
379-
#endif
380-
381336
#ifdef ABSL_HAVE_CONSTANT_EVALUATED
382337

383338
constexpr int64_t NegateIfConstantEvaluated(int64_t i) {

0 commit comments

Comments
 (0)