diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index f713b78cc6a..43bed50025b 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -495,11 +495,18 @@ using swap_internal::StdSwapIsUnconstrained; // Upstream documentation: // // https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable -// -#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) + // If the compiler offers a builtin that tells us the answer, we can use that. // This covers all of the cases in the fallback below, plus types that opt in // using e.g. [[clang::trivial_abi]]. +// +// Clang on Windows has the builtin, but it falsely claims types with a +// user-provided destructor are trivial (http://b/275003464). So we opt out +// there. +// +// TODO(b/275003464): remove the opt-out once the bug is fixed. +#if ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \ + !(defined(__clang__) && (defined(_WIN32) || defined(_WIN64))) template struct is_trivially_relocatable : std::integral_constant {}; diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index d9e3688761f..7412f33de32 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -780,20 +780,6 @@ TEST(TriviallyRelocatable, UserProvidedCopyConstructor) { static_assert(!absl::is_trivially_relocatable::value, ""); } -// HACK: disable this test on Windows, which includes lexan, which gives the -// incorrect result for this case (http://b/275003464). -// -// TODO(b/275003464): make this hack more precise after figuring out how to -// detect --config=lexan in particular. If there is no reliable way, modify -// --config=lexan itself to set a define we can use. -// -// TODO(b/274984172): hoist this hack to the definition of -// absl::is_trivially_relocatable itself, since it's currently giving the wrong -// results under lexan. We can't trust __is_trivially_relocatable on that -// platform. -// -// TODO(b/275003464): remove this hack when the bug is fixed. -#if !(defined(_WIN32) || defined(_WIN64)) // A user-provided destructor disqualifies a type from being trivially // relocatable. TEST(TriviallyRelocatable, UserProvidedDestructor) { @@ -803,10 +789,12 @@ TEST(TriviallyRelocatable, UserProvidedDestructor) { static_assert(!absl::is_trivially_relocatable::value, ""); } -#endif -#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \ - ABSL_HAVE_BUILTIN(__is_trivially_relocatable) +// TODO(b/275003464): remove the opt-out for Clang on Windows once +// __is_trivially_relocatable is used there again. +#if defined(ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI) && \ + ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && \ + !(defined(__clang__) && (defined(_WIN32) || defined(_WIN64))) // A type marked with the "trivial ABI" attribute is trivially relocatable even // if it has user-provided move/copy constructors and a user-provided // destructor.