Skip to content

[Clang] Deprecate __is_trivially_relocatable #138835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

cor3ntin
Copy link
Contributor

@cor3ntin cor3ntin commented May 7, 2025

The C++26 standard relocatable type traits has slightly different semantics, so we introduced a new __builtin_is_cpp_trivially_relocatable when implementing trivial relocation in #127636.

However, having multiple relocatable traits would be confusing in the long run, so we deprecate the old trait.

As discussed in #127636

__builtin_is_cpp_trivially_relocatable should be used instead.

The C++26 standard relocatable type traits has slightly different
semantics, so we introduced a new ``__builtin_is_cpp_trivially_relocatable``
when implementing trivial relocation in llvm#127636.

However, having multiple relocatable traits would be confusing
in the long run, so we deprecate the old trait.

As discussed in llvm#127636

`__builtin_is_cpp_trivially_relocatable` should be used instead.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 7, 2025
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-clang

Author: cor3ntin (cor3ntin)

Changes

The C++26 standard relocatable type traits has slightly different semantics, so we introduced a new __builtin_is_cpp_trivially_relocatable when implementing trivial relocation in #127636.

However, having multiple relocatable traits would be confusing in the long run, so we deprecate the old trait.

As discussed in #127636

__builtin_is_cpp_trivially_relocatable should be used instead.


Patch is 22.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138835.diff

7 Files Affected:

  • (modified) clang/docs/LanguageExtensions.rst (+7-1)
  • (modified) clang/docs/ReleaseNotes.rst (+9)
  • (modified) clang/include/clang/Basic/TokenKinds.def (+4-2)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+3)
  • (modified) clang/test/SemaCXX/attr-trivial-abi.cpp (+83-33)
  • (modified) clang/test/SemaCXX/ptrauth-triviality.cpp (+24-11)
  • (modified) clang/test/SemaCXX/type-traits-nonobject.cpp (+10-6)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index ebcad44197ce4..df5ba6304959d 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1859,12 +1859,18 @@ The following type trait primitives are supported by Clang. Those traits marked
 * ``__is_trivially_constructible`` (C++, GNU, Microsoft)
 * ``__is_trivially_copyable`` (C++, GNU, Microsoft)
 * ``__is_trivially_destructible`` (C++, MSVC 2013)
-* ``__is_trivially_relocatable`` (Clang): Returns true if moving an object
+* ``__is_trivially_relocatable`` (Clang) (Deprecated,
+   use ``__builtin_is_cpp_trivially_relocatable`` instead).
+  Returns true if moving an object
   of the given type, and then destroying the source object, is known to be
   functionally equivalent to copying the underlying bytes and then dropping the
   source object on the floor. This is true of trivial types,
   C++26 relocatable types, and types which
   were made trivially relocatable via the ``clang::trivial_abi`` attribute.
+  This trait is deprecated and should be replaced by
+  ``__builtin_is_cpp_trivially_relocatable``. Note however that it is generally
+  unsafe to relocate a C++-relocatable type with ``memcpy`` or ``memmove``;
+  use ``__builtin_trivially_relocate``.
 * ``__builtin_is_cpp_trivially_relocatable`` (C++): Returns true if an object
   is trivially relocatable, as defined by the C++26 standard [meta.unary.prop].
   Note that when relocating the caller code should ensure that if the object is polymorphic,
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 55f774f5a672e..ab3b018c3b822 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -574,6 +574,15 @@ Bug Fixes to Compiler Builtins
 - ``__has_unique_object_representations(Incomplete[])`` is no longer accepted, per
   `LWG4113 <https://cplusplus.github.io/LWG/issue4113>`_.
 
+- ``__builtin_is_cpp_trivially_relocatable``, ``__builtin_is_replaceable`` and
+  ``__builtin_trivially_relocate`` have been added to support standard C++26 relocation.
+
+- ``__is_trivially_relocatable`` has been deprecated, and uses should be replaced by
+  ``__builtin_is_cpp_trivially_relocatable``.
+  Note that, it is generally unsafe to ``memcpy`` non-trivially copyable types that
+  are ``__builtin_is_cpp_trivially_relocatable``. It is recommanded to use
+  ``__builtin_trivially_relocate`` instead.
+
 Bug Fixes to Attribute Support
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  - Fixed crash when a parameter to the ``clang::annotate`` attribute evaluates to ``void``. See #GH119125
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 9bc63689d1363..94e72fea56a68 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -544,7 +544,6 @@ TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, IsPointerInterconvertibleBas
 #include "clang/Basic/TransformTypeTraits.def"
 
 // Clang-only C++ Type Traits
-TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable, KEYCXX)
 TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
 TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX)
@@ -556,8 +555,11 @@ TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary
 // IsDeducible is only used internally by clang for CTAD implementation and
 // is not exposed to users.
 TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
-TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL)
+
+// __is_trivially_relocatable is deprecated
 TYPE_TRAIT_1(__builtin_is_cpp_trivially_relocatable, IsCppTriviallyRelocatable, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
+TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL)
 TYPE_TRAIT_1(__builtin_is_replaceable, IsReplaceable, KEYCXX)
 TYPE_TRAIT_1(__builtin_structured_binding_size, StructuredBindingSize, KEYCXX)
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8bdc2300b0392..b2a982e953012 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6449,6 +6449,9 @@ void DiagnoseBuiltinDeprecation(Sema& S, TypeTrait Kind,
     case UTT_HasTrivialDestructor:
       Replacement = UTT_IsTriviallyDestructible;
       break;
+    case UTT_IsTriviallyRelocatable:
+      Replacement = clang::UTT_IsCppTriviallyRelocatable;
+      break;
     default:
       return;
   }
diff --git a/clang/test/SemaCXX/attr-trivial-abi.cpp b/clang/test/SemaCXX/attr-trivial-abi.cpp
index e018ccda2d8d9..333ab34bc5d51 100644
--- a/clang/test/SemaCXX/attr-trivial-abi.cpp
+++ b/clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-windows-msvc -std=c++11
+
 
 void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
 
@@ -10,30 +12,38 @@ class __attribute__((trivial_abi)) a { a(a &&); };
 // (And it is only trivially relocatable, currently, if it is trivial for calls.)
 // In this case, it is suppressed by an explicitly defined move constructor.
 // Similar concerns apply to later tests that have #if defined(_WIN64) && !defined(__MINGW32__)
-static_assert(!__is_trivially_relocatable(a<int>), "");
+static_assert(!__is_trivially_relocatable(a<int>), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(a<int>), "");
 #else
-static_assert(__is_trivially_relocatable(a<int>), "");
+static_assert(__is_trivially_relocatable(a<int>), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(a<int>), "");
 #endif
 
 struct [[clang::trivial_abi]] S0 {
   int a;
 };
-static_assert(__is_trivially_relocatable(S0), "");
+static_assert(__is_trivially_relocatable(S0), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S0), "");
 
 struct __attribute__((trivial_abi)) S1 {
   int a;
 };
-static_assert(__is_trivially_relocatable(S1), "");
+static_assert(__is_trivially_relocatable(S1), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S1), "");
+
 
 struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
   virtual void m();
 };
-static_assert(!__is_trivially_relocatable(S3), "");
+static_assert(!__is_trivially_relocatable(S3), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S3), "");
+
 
 struct S3_2 {
   virtual void m();
 } __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
-static_assert(!__is_trivially_relocatable(S3_2), "");
+static_assert(!__is_trivially_relocatable(S3_2), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S3_2), "");
 
 struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
   S3_3(S3_3 &&);
@@ -43,9 +53,13 @@ struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' c
 // The ClangABI4OrPS4 calling convention kind passes classes in registers if the
 // copy constructor is trivial for calls *or deleted*, while other platforms do
 // not accept deleted constructors.
-static_assert(__is_trivially_relocatable(S3_3), "");
+static_assert(__is_trivially_relocatable(S3_3), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S3_3), "");
+
 #else
-static_assert(!__is_trivially_relocatable(S3_3), "");
+static_assert(!__is_trivially_relocatable(S3_3), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S3_3), "");
+
 #endif
 
 // Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field.
@@ -54,20 +68,28 @@ struct __attribute__((trivial_abi)) S3_4 { // expected-warning {{'trivial_abi' c
   S3_4(S3_4 &&);
   S3_2 s32;
 };
-static_assert(!__is_trivially_relocatable(S3_4<int>), "");
+static_assert(!__is_trivially_relocatable(S3_4<int>), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S3_4<int>), "");
+
 
 struct S4 {
   int a;
 };
-static_assert(__is_trivially_relocatable(S4), "");
+static_assert(__is_trivially_relocatable(S4), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S4), "");
+
 
 struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
 };
-static_assert(!__is_trivially_relocatable(S5), "");
+static_assert(!__is_trivially_relocatable(S5), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S5), "");
+
 
 struct __attribute__((trivial_abi)) S9 : public S4 {
 };
-static_assert(__is_trivially_relocatable(S9), "");
+static_assert(__is_trivially_relocatable(S9), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S9), "");
+
 
 struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
   int a;
@@ -80,8 +102,12 @@ struct __attribute__((trivial_abi)) S10 {
 };
 
 S10<int *> p1;
-static_assert(__is_trivially_relocatable(S10<int>), "");
-static_assert(__is_trivially_relocatable(S10<S3>), "");
+static_assert(__is_trivially_relocatable(S10<int>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S10<int>), "");
+
+static_assert(__is_trivially_relocatable(S10<S3>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S10<S3>), "");
+
 
 template <class T>
 struct S14 {
@@ -93,15 +119,21 @@ struct __attribute__((trivial_abi)) S15 : S14<T> {
 };
 
 S15<int> s15;
-static_assert(__is_trivially_relocatable(S15<int>), "");
-static_assert(__is_trivially_relocatable(S15<S3>), "");
+static_assert(__is_trivially_relocatable(S15<int>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S15<int>), "");
+
+static_assert(__is_trivially_relocatable(S15<S3>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S15<S3>), "");
 
 template <class T>
 struct __attribute__((trivial_abi)) S16 {
   S14<T> a;
 };
-static_assert(__is_trivially_relocatable(S16<int>), "");
-static_assert(__is_trivially_relocatable(S16<S3>), "");
+static_assert(__is_trivially_relocatable(S16<int>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S16<int>), "");
+
+static_assert(__is_trivially_relocatable(S16<S3>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S16<S3>), "");
 
 S16<int> s16;
 
@@ -110,8 +142,12 @@ struct __attribute__((trivial_abi)) S17 {
 };
 
 S17<int> s17;
-static_assert(__is_trivially_relocatable(S17<int>), "");
-static_assert(__is_trivially_relocatable(S17<S3>), "");
+static_assert(__is_trivially_relocatable(S17<int>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S17<int>), "");
+
+static_assert(__is_trivially_relocatable(S17<S3>), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S17<S3>), "");
+
 
 namespace deletedCopyMoveConstructor {
 struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
@@ -119,18 +155,24 @@ struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'tri
   CopyMoveDeleted(CopyMoveDeleted &&) = delete;
 };
 #ifdef __ORBIS__
-static_assert(__is_trivially_relocatable(CopyMoveDeleted), "");
+static_assert(__is_trivially_relocatable(CopyMoveDeleted), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(CopyMoveDeleted), "");
+
 #else
-static_assert(!__is_trivially_relocatable(CopyMoveDeleted), "");
+static_assert(!__is_trivially_relocatable(CopyMoveDeleted), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(CopyMoveDeleted), "");
+
 #endif
 
 struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
   CopyMoveDeleted a;
 };
 #ifdef __ORBIS__
-static_assert(__is_trivially_relocatable(S18), "");
+static_assert(__is_trivially_relocatable(S18), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S18), "");
 #else
-static_assert(!__is_trivially_relocatable(S18), "");
+static_assert(!__is_trivially_relocatable(S18), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S18), "");
 #endif
 
 struct __attribute__((trivial_abi)) CopyDeleted {
@@ -138,25 +180,29 @@ struct __attribute__((trivial_abi)) CopyDeleted {
   CopyDeleted(CopyDeleted &&) = default;
 };
 #if defined(_WIN64) && !defined(__MINGW32__)
-static_assert(!__is_trivially_relocatable(CopyDeleted), "");
+static_assert(!__is_trivially_relocatable(CopyDeleted), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(CopyDeleted), "");
+
 #else
-static_assert(__is_trivially_relocatable(CopyDeleted), "");
+static_assert(__is_trivially_relocatable(CopyDeleted), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(CopyDeleted), "");
 #endif
 
 struct __attribute__((trivial_abi)) MoveDeleted {
   MoveDeleted(const MoveDeleted &) = default;
   MoveDeleted(MoveDeleted &&) = delete;
 };
-static_assert(__is_trivially_relocatable(MoveDeleted), "");
-
+static_assert(__is_trivially_relocatable(MoveDeleted), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(MoveDeleted), "");
 struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}}
   CopyDeleted a;
   MoveDeleted b;
 };
 #ifdef __ORBIS__
-static_assert(__is_trivially_relocatable(S19), "");
-#else
-static_assert(!__is_trivially_relocatable(S19), "");
+static_assert(__is_trivially_relocatable(S19), ""); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S19), "");
+static_assert(!__is_trivially_relocatable(S19), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S19), "");
 #endif
 
 // This is fine since the move constructor isn't deleted.
@@ -164,8 +210,12 @@ struct __attribute__((trivial_abi)) S20 {
   int &&a; // a member of rvalue reference type deletes the copy constructor.
 };
 #if defined(_WIN64) && !defined(__MINGW32__)
-static_assert(!__is_trivially_relocatable(S20), "");
+static_assert(!__is_trivially_relocatable(S20), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S20), "");
+
 #else
-static_assert(__is_trivially_relocatable(S20), "");
+static_assert(__is_trivially_relocatable(S20), ""); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S20), "");
+
 #endif
 } // namespace deletedCopyMoveConstructor
diff --git a/clang/test/SemaCXX/ptrauth-triviality.cpp b/clang/test/SemaCXX/ptrauth-triviality.cpp
index ce6e1a7646558..785e83aaaa545 100644
--- a/clang/test/SemaCXX/ptrauth-triviality.cpp
+++ b/clang/test/SemaCXX/ptrauth-triviality.cpp
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
-// expected-no-diagnostics
 
 #define AQ __ptrauth(1,1,50)
 #define IQ __ptrauth(1,0,50)
@@ -24,7 +23,8 @@ static_assert(!__is_trivially_constructible(S1, const S1&));
 static_assert(!__is_trivially_assignable(S1, const S1&));
 static_assert(__is_trivially_destructible(S1));
 static_assert(!__is_trivially_copyable(S1));
-static_assert(!__is_trivially_relocatable(S1));
+static_assert(!__is_trivially_relocatable(S1)); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(S1));
 static_assert(!__is_trivially_equality_comparable(S1));
 
 static_assert(__is_trivially_constructible(Holder<S1>));
@@ -32,7 +32,8 @@ static_assert(!__is_trivially_constructible(Holder<S1>, const Holder<S1>&));
 static_assert(!__is_trivially_assignable(Holder<S1>, const Holder<S1>&));
 static_assert(__is_trivially_destructible(Holder<S1>));
 static_assert(!__is_trivially_copyable(Holder<S1>));
-static_assert(!__is_trivially_relocatable(Holder<S1>));
+static_assert(!__is_trivially_relocatable(Holder<S1>)); // expected-warning{{deprecated}}
+static_assert(!__builtin_is_cpp_trivially_relocatable(Holder<S1>));
 static_assert(!__is_trivially_equality_comparable(Holder<S1>));
 
 struct S2 {
@@ -45,7 +46,8 @@ static_assert(__is_trivially_constructible(S2, const S2&));
 static_assert(__is_trivially_assignable(S2, const S2&));
 static_assert(__is_trivially_destructible(S2));
 static_assert(__is_trivially_copyable(S2));
-static_assert(__is_trivially_relocatable(S2));
+static_assert(__is_trivially_relocatable(S2)); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(S2));
 static_assert(__is_trivially_equality_comparable(S2));
 
 static_assert(__is_trivially_constructible(Holder<S2>));
@@ -53,7 +55,8 @@ static_assert(__is_trivially_constructible(Holder<S2>, const Holder<S2>&));
 static_assert(__is_trivially_assignable(Holder<S2>, const Holder<S2>&));
 static_assert(__is_trivially_destructible(Holder<S2>));
 static_assert(__is_trivially_copyable(Holder<S2>));
-static_assert(__is_trivially_relocatable(Holder<S2>));
+static_assert(__is_trivially_relocatable(Holder<S2>)); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S2>));
 static_assert(__is_trivially_equality_comparable(Holder<S2>));
 
 struct AA S3 {
@@ -67,15 +70,19 @@ static_assert(!__is_trivially_constructible(S3, const S3&));
 static_assert(!__is_trivially_assignable(S3, const S3&));
 static_assert(__is_trivially_destructible(S3));
 static_assert(!__is_trivially_copyable(S3));
-static_assert(!__is_trivially_relocatable(S3));
+static_assert(!__is_trivially_relocatable(S3)); // expected-warning{{deprecated}}
+//FIXME
+static_assert(__builtin_is_cpp_trivially_relocatable(S3));
 static_assert(!__is_trivially_equality_comparable(S3));
 
+
 static_assert(!__is_trivially_constructible(Holder<S3>));
 static_assert(!__is_trivially_constructible(Holder<S3>, const Holder<S3>&));
 static_assert(!__is_trivially_assignable(Holder<S3>, const Holder<S3>&));
 static_assert(__is_trivially_destructible(Holder<S3>));
 static_assert(!__is_trivially_copyable(Holder<S3>));
-static_assert(__is_trivially_relocatable(Holder<S3>));
+static_assert(__is_trivially_relocatable(Holder<S3>)); // expected-warning{{deprecated}}
+static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S3>));
 static_assert(!__is_trivially_equality_comparable(Holder<S3>));
 
 struct IA S4 {
@@ -89,7 +96,9 @@ static_assert(!__is_trivially_constructible(S4, const S4&));
 static_assert(!__is_trivially_assignable(S4, const S4&));
 static_assert(__is_trivially_destructible(S4));
 static_assert(!__is_trivially_copyable(S4));
-static_assert(!__is_trivially_relocatable(S4));
+static_assert(!__is_trivially_relocatable(S4)); // expected-warning{{deprecated}}
+//FIXME
+static_assert(__builtin_is_cpp_trivially_relocatable(S4));
 static_assert(!__is_trivially_equality_comparable(S4));
 
 static_assert(!__is_trivially_constructible(Holder<S4>));
@@ -97,7 +106,8 @@ static_assert(!__is_trivially_constructible(Holder<S4>, const Holder<S4>&));
 static_assert(!__is_trivially_assignable(Holder<S4>, const Holder<S4>&));
 static_assert(__is_trivially_destructible(Holder<S4>));
 static_assert(!__is_trivially_copyable(Holder<S4...
[truncated]

@cor3ntin
Copy link
Contributor Author

cor3ntin commented May 7, 2025

I'll investigate separately if we can detect cases where memcpy/ memmove should be replaced by trivially_relocate

static_assert(!__is_trivially_relocatable(S4));
static_assert(!__is_trivially_relocatable(S4)); // expected-warning{{deprecated}}
//FIXME
static_assert(__builtin_is_cpp_trivially_relocatable(S4));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ojhunt I think fixing that depends on #138482

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more obnoxious than that, I've just filed #138948 - we're simply failing to consider vtable pointers.

We working out if a record contains address discriminated data we recurse over all the fields and base classes, but that does not include the vtable pointer.

A non-zero part of me wants the vtable pointer to be visible as a field in these APIs, but a much larger part of me thinks that doing so would break so many things :-D

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM generally, but not approving until @ldionne weighs in on whether this impacts libc++.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is great and I don't think it impacts libc++ since we moved off of the builtin a few months ago (in preparation for these kinds of changes).

Co-authored-by: Aaron Ballman <[email protected]>
@cor3ntin cor3ntin merged commit 43c514b into llvm:main May 7, 2025
10 of 11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented May 7, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-ubuntu-fast running on sie-linux-worker while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/24541

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang :: SemaCXX/attr-trivial-abi.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang -cc1 -internal-isystem /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/21/include -nostdsysteminc -fsyntax-only -verify /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp -std=c++11 # RUN: at line 1
+ /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang -cc1 -internal-isystem /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/21/include -nostdsysteminc -fsyntax-only -verify /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp -std=c++11
error: 'expected-error' diagnostics seen but not expected: 
  File /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp Line 57: static assertion failed due to requirement '__builtin_is_cpp_trivially_relocatable(S3_3)': 
  File /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp Line 159: static assertion failed due to requirement '__builtin_is_cpp_trivially_relocatable(deletedCopyMoveConstructor::CopyMoveDeleted)': 
  File /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp Line 172: static assertion failed due to requirement '__builtin_is_cpp_trivially_relocatable(deletedCopyMoveConstructor::S18)': 
  File /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp Line 203: static assertion failed due to requirement '__builtin_is_cpp_trivially_relocatable(deletedCopyMoveConstructor::S19)': 
  File /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaCXX/attr-trivial-abi.cpp Line 204: static assertion failed due to requirement '!__is_trivially_relocatable(deletedCopyMoveConstructor::S19)': 
5 errors generated.

--

********************


@dyung
Copy link
Collaborator

dyung commented May 8, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-ubuntu-fast running on sie-linux-worker while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/24541

Here is the relevant piece of the build log for the reference

@cor3ntin can you take a look at this failure or revert to get the bot back to green?

dyung added a commit that referenced this pull request May 8, 2025
dyung added a commit that referenced this pull request May 8, 2025
@dyung
Copy link
Collaborator

dyung commented May 8, 2025

@cor3ntin I've reverted the commit to get the bot back to green. Please look into the failure when you try to reland the change.

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 8, 2025
petrhosek pushed a commit to petrhosek/llvm-project that referenced this pull request May 8, 2025
The C++26 standard relocatable type traits has slightly different
semantics, so we introduced a new
``__builtin_is_cpp_trivially_relocatable`` when implementing trivial
relocation in llvm#127636.

However, having multiple relocatable traits would be confusing in the
long run, so we deprecate the old trait.

As discussed in llvm#127636

`__builtin_is_cpp_trivially_relocatable` should be used instead.

---------

Co-authored-by: Aaron Ballman <[email protected]>
petrhosek pushed a commit to petrhosek/llvm-project that referenced this pull request May 8, 2025
copybara-service bot pushed a commit to abseil/abseil-cpp that referenced this pull request May 8, 2025
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
aarongable pushed a commit to chromium/chromium that referenced this pull request May 12, 2025
…able

__is_trivially_relocatable is deprecated since
llvm/llvm-project#138835

Bug: 416394845
Change-Id: I10c9e8a2adec49f9f3b3b7c3606bdf7027b01a10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6534163
Reviewed-by: Daniel Cheng <[email protected]>
Auto-Submit: Hans Wennborg <[email protected]>
Commit-Queue: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1458903}
github-actions bot pushed a commit to kaidokert/chrome_base_mirror that referenced this pull request May 13, 2025
…able

__is_trivially_relocatable is deprecated since
llvm/llvm-project#138835

Bug: 416394845
Change-Id: I10c9e8a2adec49f9f3b3b7c3606bdf7027b01a10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6534163
Reviewed-by: Daniel Cheng <[email protected]>
Auto-Submit: Hans Wennborg <[email protected]>
Commit-Queue: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1458903}
NOKEYCHECK=True
GitOrigin-RevId: 4ed2c83bf081877d7929eb20655fe4768f71c984
jrguzman-ms pushed a commit to msft-mirror-aosp/platform.external.libchrome that referenced this pull request May 27, 2025
…able

__is_trivially_relocatable is deprecated since
llvm/llvm-project#138835

Bug: 416394845
Change-Id: I10c9e8a2adec49f9f3b3b7c3606bdf7027b01a10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6534163
Reviewed-by: Daniel Cheng <[email protected]>
Auto-Submit: Hans Wennborg <[email protected]>
Commit-Queue: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1458903}


CrOS-Libchrome-Original-Commit: 4ed2c83bf081877d7929eb20655fe4768f71c984
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants