Skip to content

Conversation

@llvmbot
Copy link
Member

@llvmbot llvmbot commented Aug 26, 2025

Backport d66b537

Requested by: @ojhunt

@llvmbot
Copy link
Member Author

llvmbot commented Aug 26, 2025

@cor3ntin What do you think about merging this PR to the release branch?

@llvmbot llvmbot requested a review from cor3ntin August 26, 2025 20:25
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 26, 2025
@llvmbot
Copy link
Member Author

llvmbot commented Aug 26, 2025

@llvm/pr-subscribers-clang

Author: None (llvmbot)

Changes

Backport d66b537

Requested by: @ojhunt


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

9 Files Affected:

  • (modified) clang/include/clang/AST/ASTContext.h (+5-6)
  • (modified) clang/lib/AST/ASTContext.cpp (+5-4)
  • (modified) clang/lib/AST/DeclCXX.cpp (+7)
  • (modified) clang/lib/AST/Type.cpp (+20)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+1)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+4-1)
  • (modified) clang/test/SemaCXX/ptrauth-triviality.cpp (+3-3)
  • (added) clang/test/SemaCXX/ptrauth-type-traits.cpp (+401)
  • (modified) clang/test/SemaCXX/trivially-relocatable-ptrauth.cpp (+2-2)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 8c27728c404dd..c0e702dba8d5a 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -634,7 +634,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// contain data that is address discriminated. This includes
   /// implicitly authenticated values like vtable pointers, as well as
   /// explicitly qualified fields.
-  bool containsAddressDiscriminatedPointerAuth(QualType T) {
+  bool containsAddressDiscriminatedPointerAuth(QualType T) const {
     if (!isPointerAuthenticationAvailable())
       return false;
     return findPointerAuthContent(T) != PointerAuthContent::None;
@@ -648,8 +648,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   bool containsNonRelocatablePointerAuth(QualType T) {
     if (!isPointerAuthenticationAvailable())
       return false;
-    return findPointerAuthContent(T) ==
-           PointerAuthContent::AddressDiscriminatedData;
+    return findPointerAuthContent(T) != PointerAuthContent::None;
   }
 
 private:
@@ -667,8 +666,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
   bool isPointerAuthenticationAvailable() const {
     return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
   }
-  PointerAuthContent findPointerAuthContent(QualType T);
-  llvm::DenseMap<const RecordDecl *, PointerAuthContent>
+  PointerAuthContent findPointerAuthContent(QualType T) const;
+  mutable llvm::DenseMap<const RecordDecl *, PointerAuthContent>
       RecordContainsAddressDiscriminatedPointerAuth;
 
   ImportDecl *FirstLocalImport = nullptr;
@@ -3698,7 +3697,7 @@ OPT_LIST(V)
   /// Resolve the root record to be used to derive the vtable pointer
   /// authentication policy for the specified record.
   const CXXRecordDecl *
-  baseForVTableAuthentication(const CXXRecordDecl *ThisClass);
+  baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const;
 
   bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
                                StringRef MangledName);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 0499a81cd5231..61455ac48287d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1706,7 +1706,7 @@ void ASTContext::setRelocationInfoForCXXRecord(
 }
 
 static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
-    ASTContext &Context, const CXXRecordDecl *Class) {
+    const ASTContext &Context, const CXXRecordDecl *Class) {
   if (!Class->isPolymorphic())
     return false;
   const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class);
@@ -1721,7 +1721,8 @@ static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
   return AddressDiscrimination == AuthAttr::AddressDiscrimination;
 }
 
-ASTContext::PointerAuthContent ASTContext::findPointerAuthContent(QualType T) {
+ASTContext::PointerAuthContent
+ASTContext::findPointerAuthContent(QualType T) const {
   assert(isPointerAuthenticationAvailable());
 
   T = T.getCanonicalType();
@@ -3032,7 +3033,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
     return true;
   }
 
-  // All other pointers (except __ptrauth pointers) are unique.
+  // All other pointers are unique.
   if (Ty->isPointerType())
     return !Ty.hasAddressDiscriminatedPointerAuth();
 
@@ -15106,7 +15107,7 @@ StringRef ASTContext::getCUIDHash() const {
 }
 
 const CXXRecordDecl *
-ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {
+ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const {
   assert(ThisClass);
   assert(ThisClass->isPolymorphic());
   const CXXRecordDecl *PrimaryBase = ThisClass;
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 4514965009793..64895f4fb9d45 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1448,6 +1448,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
         data().StructuralIfLiteral = false;
     }
 
+    // If this type contains any address discriminated values we should
+    // have already indicated that the only special member functions that
+    // can possibly be trivial are the default constructor and destructor.
+    if (T.hasAddressDiscriminatedPointerAuth())
+      data().HasTrivialSpecialMembers &=
+          SMF_DefaultConstructor | SMF_Destructor;
+
     // C++14 [meta.unary.prop]p4:
     //   T is a class type [...] with [...] no non-static data members other
     //   than subobjects of zero size
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e5a1ab2ff8906..65024fcb1b7c3 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2715,6 +2715,11 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
     return false;
 
   QualType CanonicalType = getTypePtr()->CanonicalType;
+
+  // Any type that is, or contains, address discriminated data is never POD.
+  if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
+    return false;
+
   switch (CanonicalType->getTypeClass()) {
     // Everything not explicitly mentioned is not POD.
   default:
@@ -2773,6 +2778,11 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
   if (CanonicalType->isDependentType())
     return false;
 
+  // Any type that is, or contains, address discriminated data is never a
+  // trivial type.
+  if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
+    return false;
+
   // C++0x [basic.types]p9:
   //   Scalar types, trivial class types, arrays of such types, and
   //   cv-qualified versions of these types are collectively called trivial
@@ -2870,6 +2880,12 @@ bool QualType::isBitwiseCloneableType(const ASTContext &Context) const {
 
   if (CanonicalType->isIncompleteType())
     return false;
+
+  // Any type that is, or contains, address discriminated data is never
+  // bitwise clonable.
+  if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
+    return false;
+
   const auto *RD = CanonicalType->getAsRecordDecl(); // struct/union/class
   if (!RD)
     return true;
@@ -3115,6 +3131,10 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
   if (BaseTy->isIncompleteType())
     return false;
 
+  // Any type that is, or contains, address discriminated data is non-POD.
+  if (Context.containsAddressDiscriminatedPointerAuth(*this))
+    return false;
+
   // As an extension, Clang treats vector types as Scalar types.
   if (BaseTy->isScalarType() || BaseTy->isVectorType())
     return true;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index bb412ef6788e7..d43dc2297c6fb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19651,6 +19651,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
                  Q && Q.isAddressDiscriminated()) {
         Record->setArgPassingRestrictions(
             RecordArgPassingKind::CanNeverPassInRegs);
+        Record->setNonTrivialToPrimitiveCopy(true);
       }
     }
 
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 1d8687e4bf1c1..79cda40a0edb2 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1768,7 +1768,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
       // Objective-C lifetime, this is a non-trivial assignment.
       if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
         return false;
-
+      const ASTContext &Context = Self.getASTContext();
+      if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
+          Context.containsAddressDiscriminatedPointerAuth(RhsT))
+        return false;
       return !Result.get()->hasNonTrivialCall(Self.Context);
     }
 
diff --git a/clang/test/SemaCXX/ptrauth-triviality.cpp b/clang/test/SemaCXX/ptrauth-triviality.cpp
index ba8a8273d5c05..b1b334b59a59e 100644
--- a/clang/test/SemaCXX/ptrauth-triviality.cpp
+++ b/clang/test/SemaCXX/ptrauth-triviality.cpp
@@ -74,7 +74,7 @@ static_assert(__is_trivially_destructible(S3));
 static_assert(!__is_trivially_copyable(S3));
 static_assert(!__is_trivially_relocatable(S3)); // expected-warning{{deprecated}}
 //FIXME
-static_assert(__builtin_is_cpp_trivially_relocatable(S3));
+static_assert(!__builtin_is_cpp_trivially_relocatable(S3));
 static_assert(!__is_trivially_equality_comparable(S3));
 
 
@@ -84,7 +84,7 @@ 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>)); // expected-warning{{deprecated}}
-static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S3>));
+static_assert(!__builtin_is_cpp_trivially_relocatable(Holder<S3>));
 static_assert(!__is_trivially_equality_comparable(Holder<S3>));
 
 struct IA S4 {
@@ -207,7 +207,7 @@ template <class T> struct UnionWrapper trivially_relocatable_if_eligible {
   } u;
 };
 
-static_assert(test_is_trivially_relocatable_v<AddressDiscriminatedPolymorphicBase>);
+static_assert(!test_is_trivially_relocatable_v<AddressDiscriminatedPolymorphicBase>);
 static_assert(test_is_trivially_relocatable_v<NoAddressDiscriminatedPolymorphicBase>);
 static_assert(inheritance_relocatability_matches_bases_v<AddressDiscriminatedPolymorphicBase, NoAddressDiscriminatedPolymorphicBase>);
 static_assert(inheritance_relocatability_matches_bases_v<NoAddressDiscriminatedPolymorphicBase, AddressDiscriminatedPolymorphicBase>);
diff --git a/clang/test/SemaCXX/ptrauth-type-traits.cpp b/clang/test/SemaCXX/ptrauth-type-traits.cpp
new file mode 100644
index 0000000000000..aefbd63fa1677
--- /dev/null
+++ b/clang/test/SemaCXX/ptrauth-type-traits.cpp
@@ -0,0 +1,401 @@
+// RUN: %clang_cc1 -triple arm64               -std=c++26 -Wno-deprecated-builtins \
+// RUN:                                        -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-apple-darwin -fptrauth-calls -fptrauth-intrinsics \
+// RUN:                                       -fptrauth-vtable-pointer-address-discrimination \
+// RUN:                                       -std=c++26 -Wno-deprecated-builtins \
+// RUN:                                       -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+#ifdef __PTRAUTH__
+
+#define NonAddressDiscriminatedVTablePtrAttr \
+  [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]]
+#define AddressDiscriminatedVTablePtrAttr \
+  [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, no_extra_discrimination)]]
+#define ADDR_DISC_ENABLED true
+#else
+#define NonAddressDiscriminatedVTablePtrAttr
+#define AddressDiscriminatedVTablePtrAttr
+#define ADDR_DISC_ENABLED false
+#define __ptrauth(...)
+#endif
+
+
+typedef int* __ptrauth(1,1,1) AddressDiscriminatedPtr;
+typedef __UINT64_TYPE__ __ptrauth(1,1,1) AddressDiscriminatedInt64;
+struct AddressDiscriminatedFields {
+  AddressDiscriminatedPtr ptr;
+};
+struct RelocatableAddressDiscriminatedFields trivially_relocatable_if_eligible {
+  AddressDiscriminatedPtr ptr;
+};
+struct AddressDiscriminatedFieldInBaseClass : AddressDiscriminatedFields {
+  void *newfield;
+};
+
+struct NonAddressDiscriminatedVTablePtrAttr NonAddressDiscriminatedVTablePtr {
+  virtual ~NonAddressDiscriminatedVTablePtr();
+  void *i;
+};
+
+struct NonAddressDiscriminatedVTablePtrAttr NonAddressDiscriminatedVTablePtr2 {
+  virtual ~NonAddressDiscriminatedVTablePtr2();
+  void *j;
+};
+
+struct NonAddressDiscriminatedVTablePtrAttr RelocatableNonAddressDiscriminatedVTablePtr trivially_relocatable_if_eligible {
+  virtual ~RelocatableNonAddressDiscriminatedVTablePtr();
+  void *i;
+};
+
+struct NonAddressDiscriminatedVTablePtrAttr RelocatableNonAddressDiscriminatedVTablePtr2 trivially_relocatable_if_eligible {
+  virtual ~RelocatableNonAddressDiscriminatedVTablePtr2();
+  void *j;
+};
+
+struct AddressDiscriminatedVTablePtrAttr AddressDiscriminatedVTablePtr {
+  virtual ~AddressDiscriminatedVTablePtr();
+  void *k;
+};
+
+struct AddressDiscriminatedVTablePtrAttr RelocatableAddressDiscriminatedVTablePtr trivially_relocatable_if_eligible {
+  virtual ~RelocatableAddressDiscriminatedVTablePtr();
+  void *k;
+};
+
+struct NoAddressDiscriminatedBaseClasses : NonAddressDiscriminatedVTablePtr,
+                                           NonAddressDiscriminatedVTablePtr2 {
+  void *l;
+};
+
+struct RelocatableNoAddressDiscriminatedBaseClasses trivially_relocatable_if_eligible :
+                                           NonAddressDiscriminatedVTablePtr,
+                                           NonAddressDiscriminatedVTablePtr2 {
+  void *l;
+};
+
+struct AddressDiscriminatedPrimaryBase : AddressDiscriminatedVTablePtr,
+                                         NonAddressDiscriminatedVTablePtr {
+  void *l;
+};
+struct AddressDiscriminatedSecondaryBase : NonAddressDiscriminatedVTablePtr,
+                                           AddressDiscriminatedVTablePtr {
+  void *l;
+};
+
+struct RelocatableAddressDiscriminatedPrimaryBase : RelocatableAddressDiscriminatedVTablePtr,
+                                         RelocatableNonAddressDiscriminatedVTablePtr {
+  void *l;
+};
+struct RelocatableAddressDiscriminatedSecondaryBase : RelocatableNonAddressDiscriminatedVTablePtr,
+                                           RelocatableAddressDiscriminatedVTablePtr {
+  void *l;
+};
+struct EmbdeddedAddressDiscriminatedPolymorphicClass {
+  AddressDiscriminatedVTablePtr field;
+};
+struct RelocatableEmbdeddedAddressDiscriminatedPolymorphicClass trivially_relocatable_if_eligible {
+  AddressDiscriminatedVTablePtr field;
+};
+
+static_assert( __is_pod(AddressDiscriminatedPtr) == !ADDR_DISC_ENABLED);
+static_assert( __is_pod(AddressDiscriminatedInt64) == !ADDR_DISC_ENABLED);
+static_assert( __is_pod(AddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __is_pod(RelocatableAddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert(!__is_pod(AddressDiscriminatedFieldInBaseClass));
+static_assert(!__is_pod(NonAddressDiscriminatedVTablePtr));
+static_assert(!__is_pod(NonAddressDiscriminatedVTablePtr2));
+static_assert(!__is_pod(RelocatableNonAddressDiscriminatedVTablePtr));
+static_assert(!__is_pod(RelocatableNonAddressDiscriminatedVTablePtr2));
+static_assert(!__is_pod(AddressDiscriminatedVTablePtr));
+static_assert(!__is_pod(RelocatableAddressDiscriminatedVTablePtr));
+static_assert(!__is_pod(NoAddressDiscriminatedBaseClasses));
+static_assert(!__is_pod(RelocatableNoAddressDiscriminatedBaseClasses));
+static_assert(!__is_pod(AddressDiscriminatedPrimaryBase));
+static_assert(!__is_pod(AddressDiscriminatedSecondaryBase));
+static_assert(!__is_pod(RelocatableAddressDiscriminatedPrimaryBase));
+static_assert(!__is_pod(RelocatableAddressDiscriminatedSecondaryBase));
+static_assert(!__is_pod(EmbdeddedAddressDiscriminatedPolymorphicClass));
+static_assert(!__is_pod(RelocatableEmbdeddedAddressDiscriminatedPolymorphicClass));
+
+static_assert( __is_standard_layout(AddressDiscriminatedPtr));
+static_assert( __is_standard_layout(AddressDiscriminatedInt64));
+static_assert( __is_standard_layout(AddressDiscriminatedFields));
+static_assert( __is_standard_layout(RelocatableAddressDiscriminatedFields));
+static_assert(!__is_standard_layout(AddressDiscriminatedFieldInBaseClass));
+static_assert(!__is_standard_layout(NonAddressDiscriminatedVTablePtr));
+static_assert(!__is_standard_layout(NonAddressDiscriminatedVTablePtr2));
+static_assert(!__is_standard_layout(RelocatableNonAddressDiscriminatedVTablePtr));
+static_assert(!__is_standard_layout(RelocatableNonAddressDiscriminatedVTablePtr2));
+static_assert(!__is_standard_layout(AddressDiscriminatedVTablePtr));
+static_assert(!__is_standard_layout(RelocatableAddressDiscriminatedVTablePtr));
+static_assert(!__is_standard_layout(NoAddressDiscriminatedBaseClasses));
+static_assert(!__is_standard_layout(RelocatableNoAddressDiscriminatedBaseClasses));
+static_assert(!__is_standard_layout(AddressDiscriminatedPrimaryBase));
+static_assert(!__is_standard_layout(AddressDiscriminatedSecondaryBase));
+static_assert(!__is_standard_layout(RelocatableAddressDiscriminatedPrimaryBase));
+static_assert(!__is_standard_layout(RelocatableAddressDiscriminatedSecondaryBase));
+static_assert(!__is_standard_layout(EmbdeddedAddressDiscriminatedPolymorphicClass));
+static_assert(!__is_standard_layout(RelocatableEmbdeddedAddressDiscriminatedPolymorphicClass));
+
+static_assert( __has_trivial_move_constructor(AddressDiscriminatedPtr) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_move_constructor(AddressDiscriminatedInt64) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_move_constructor(AddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_move_constructor(RelocatableAddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_move_constructor(AddressDiscriminatedFieldInBaseClass) == !ADDR_DISC_ENABLED);
+static_assert(!__has_trivial_move_constructor(NonAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_move_constructor(NonAddressDiscriminatedVTablePtr2));
+static_assert(!__has_trivial_move_constructor(RelocatableNonAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_move_constructor(RelocatableNonAddressDiscriminatedVTablePtr2));
+static_assert(!__has_trivial_move_constructor(AddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_move_constructor(RelocatableAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_move_constructor(NoAddressDiscriminatedBaseClasses));
+static_assert(!__has_trivial_move_constructor(RelocatableNoAddressDiscriminatedBaseClasses));
+static_assert(!__has_trivial_move_constructor(AddressDiscriminatedPrimaryBase));
+static_assert(!__has_trivial_move_constructor(AddressDiscriminatedSecondaryBase));
+static_assert(!__has_trivial_move_constructor(RelocatableAddressDiscriminatedPrimaryBase));
+static_assert(!__has_trivial_move_constructor(RelocatableAddressDiscriminatedSecondaryBase));
+static_assert(!__has_trivial_move_constructor(EmbdeddedAddressDiscriminatedPolymorphicClass));
+static_assert(!__has_trivial_move_constructor(RelocatableEmbdeddedAddressDiscriminatedPolymorphicClass));
+
+static_assert( __has_trivial_copy(AddressDiscriminatedPtr) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_copy(AddressDiscriminatedInt64) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_copy(AddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_copy(RelocatableAddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_copy(AddressDiscriminatedFieldInBaseClass) == !ADDR_DISC_ENABLED);
+static_assert(!__has_trivial_copy(NonAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_copy(NonAddressDiscriminatedVTablePtr2));
+static_assert(!__has_trivial_copy(RelocatableNonAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_copy(RelocatableNonAddressDiscriminatedVTablePtr2));
+static_assert(!__has_trivial_copy(AddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_copy(RelocatableAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_copy(NoAddressDiscriminatedBaseClasses));
+static_assert(!__has_trivial_copy(RelocatableNoAddressDiscriminatedBaseClasses));
+static_assert(!__has_trivial_copy(AddressDiscriminatedPrimaryBase));
+static_assert(!__has_trivial_copy(AddressDiscriminatedSecondaryBase));
+static_assert(!__has_trivial_copy(RelocatableAddressDiscriminatedPrimaryBase));
+static_assert(!__has_trivial_copy(RelocatableAddressDiscriminatedSecondaryBase));
+static_assert(!__has_trivial_copy(EmbdeddedAddressDiscriminatedPolymorphicClass));
+static_assert(!__has_trivial_copy(RelocatableEmbdeddedAddressDiscriminatedPolymorphicClass));
+
+static_assert( __has_trivial_assign(AddressDiscriminatedPtr) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_assign(AddressDiscriminatedInt64) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_assign(AddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_assign(RelocatableAddressDiscriminatedFields) == !ADDR_DISC_ENABLED);
+static_assert( __has_trivial_assign(AddressDiscriminatedFieldInBaseClass) == !ADDR_DISC_ENABLED);
+static_assert(!__has_trivial_assign(NonAddressDiscriminatedVTablePtr));
+static_assert(!__has_trivial_assign(NonAddre...
[truncated]

@github-project-automation github-project-automation bot moved this from Needs Triage to Needs Merge in LLVM Release Status Aug 26, 2025
…bitwise compatible (llvm#154490)

A number of builtins report some variation of "this type is compatibile
with some bitwise equivalent operation", but this is not true for
address discriminated values. We had address a number of cases, but not
all of them. This PR corrects the remaining builtins.

Fixes llvm#154394

(cherry picked from commit d66b537)
/// implicitly authenticated values like vtable pointers, as well as
/// explicitly qualified fields.
bool containsAddressDiscriminatedPointerAuth(QualType T) {
bool containsAddressDiscriminatedPointerAuth(QualType T) const {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like an ABI breaking change.

Copy link
Contributor

Choose a reason for hiding this comment

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

This has not shipped - llvm21 is the first version of llvm to include any of the pointer auth work.

That said it's irksome that we don't have a way to indicate that functions are not intended to be API, or that there is no abstraction layer for the API given that ASTContext is used for both internal semantic checks and apparently is part of the API (it did not occur to me that anything here would be directly exposed as API as none of the changes I have made have ever triggered any kind of API review) :-/

Copy link
Contributor

Choose a reason for hiding this comment

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

This has not shipped - llvm21 is the first version of llvm to include any of the pointer auth work.

LLVM 21.1.0 has been released, so all backports from this point on must be ABI compatible.

That said it's irksome that we don't have a way to indicate that functions are not intended to be API, or that there is no abstraction layer for the API given that ASTContext is used for both internal semantic checks and apparently is part of the API (it did not occur to me that anything here would be directly exposed as API as none of the changes I have made have ever triggered any kind of API review) :-/

This may be possible in the future using ABI annotations, but the clang-side work for that hasn't really started yet.

For the purposes of this backport, you'll have to rewrite this without the const qualifiers.

Copy link
Contributor

Choose a reason for hiding this comment

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

@nikic this was targeting that release - I thought we had until the 28th?

Copy link
Contributor

Choose a reason for hiding this comment

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

anyway, if that has shipped there's nothing we can do now except publish errata on broken behavior here

Copy link
Contributor

Choose a reason for hiding this comment

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

@nikic this was targeting that release - I thought we had until the 28th?

You can find the release schedule in the sidebar on https://llvm.org/. The general rule is that LLVM always releases on Tuesdays.

anyway, if that has shipped there's nothing we can do now except publish errata on broken behavior here

Why can't you just drop all the const qualifiers from this patch? That should be sufficient to avoid changing the symbol mangling.

@nikic nikic moved this from Needs Merge to Needs Review in LLVM Release Status Aug 26, 2025
@ojhunt ojhunt self-assigned this Aug 26, 2025
@ojhunt
Copy link
Contributor

ojhunt commented Aug 26, 2025

Superseded by #155513

@ojhunt ojhunt closed this Aug 26, 2025
@nikic nikic moved this from Needs Review to Won't Merge in LLVM Release Status Sep 1, 2025
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

Status: Won't Merge

Development

Successfully merging this pull request may close these issues.

4 participants