https://github.com/ojhunt created 
https://github.com/llvm/llvm-project/pull/172186

None

>From 7c547005228cdb185fc0f5458c62d0c24e2df9b6 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <[email protected]>
Date: Sat, 13 Dec 2025 00:39:04 -0800
Subject: [PATCH 1/2] start refactoring the ptrauth thingy

---
 clang/include/clang/AST/ASTContext.h          | 28 +++++++++++------
 clang/include/clang/Basic/DiagnosticGroups.td |  1 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  3 ++
 clang/lib/AST/ASTContext.cpp                  | 31 ++++++++++---------
 4 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index f64e29be3205f..271fb831406fb 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -681,7 +681,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   bool containsAddressDiscriminatedPointerAuth(QualType T) const {
     if (!isPointerAuthenticationAvailable())
       return false;
-    return findPointerAuthContent(T) != PointerAuthContent::None;
+    return (findPointerAuthContent(T) & 
PointerAuthContent::ContainsAddressDiscriminatedData) != 
PointerAuthContent::ContainsNone;
   }
 
   /// Examines a given type, and returns whether the type itself
@@ -692,7 +692,18 @@ class ASTContext : public RefCountedBase<ASTContext> {
   bool containsNonRelocatablePointerAuth(QualType T) {
     if (!isPointerAuthenticationAvailable())
       return false;
-    return findPointerAuthContent(T) != PointerAuthContent::None;
+    return (findPointerAuthContent(T) & 
PointerAuthContent::ContainsAddressDiscriminatedData) != 
PointerAuthContent::ContainsNone;
+  }
+
+  bool containsDefaultAuthenticatedFunctionPointer(QualType T) {
+    if (!isPointerAuthenticationAvailable())
+      return false;
+    return (findPointerAuthContent(T) & 
PointerAuthContent::ContainsDefaultAuthenticatedFunction) != 
PointerAuthContent::ContainsNone;
+  }
+
+  // A simple helper function to short circuit pointer auth checks.
+  bool isPointerAuthenticationAvailable() const {
+    return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
   }
 
 private:
@@ -701,15 +712,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
 
   // FIXME: store in RecordDeclBitfields in future?
   enum class PointerAuthContent : uint8_t {
-    None,
-    AddressDiscriminatedVTable,
-    AddressDiscriminatedData
+    ContainsNone = 0,
+    ContainsAddressDiscriminatedVTable = 1 << 0,
+    ContainsAddressDiscriminatedData = 1 << 1,
+    ContainsDefaultAuthenticatedFunction = 1 << 2,
+    ContainsAllFlags = ContainsAddressDiscriminatedVTable | 
ContainsAddressDiscriminatedData | ContainsDefaultAuthenticatedFunction,
+    
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ContainsDefaultAuthenticatedFunction)
   };
 
-  // A simple helper function to short circuit pointer auth checks.
-  bool isPointerAuthenticationAvailable() const {
-    return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
-  }
   PointerAuthContent findPointerAuthContent(QualType T) const;
   mutable llvm::DenseMap<const RecordDecl *, PointerAuthContent>
       RecordContainsAddressDiscriminatedPointerAuth;
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index e1dba0195f470..16434f9f9dd46 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1081,6 +1081,7 @@ def GNUZeroLineDirective : 
DiagGroup<"gnu-zero-line-directive">;
 def GNUZeroVariadicMacroArguments : 
DiagGroup<"gnu-zero-variadic-macro-arguments", [VariadicMacroArgumentsOmitted]>;
 def MisleadingIndentation : DiagGroup<"misleading-indentation">;
 def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">;
+def PtrAuthWeakSchema : DiagGroup<"ptrauth-weak-schema">;
 
 // This covers both the deprecated case (in C++98)
 // and the extension case (in C++11 onwards).
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 381d1fb063eba..46cfdf85e504a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1018,6 +1018,9 @@ def err_ptrauth_string_not_literal : Error<
 def err_ptrauth_type_disc_undiscriminated : Error<
   "cannot pass undiscriminated type %0 to "
   "'__builtin_ptrauth_type_discriminator'">;
+def warn_ptrauth_weak_global_function_pointer :
+  Warning<"global pointer %0 uses the default pointer authentication schema">,
+  InGroup<PtrAuthWeakSchema>;
 
 def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
   Note<"cannot take an address of a virtual member function if its return or "
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f4aadeceb4bb7..e1e6f5015cf68 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1640,23 +1640,27 @@ ASTContext::findPointerAuthContent(QualType T) const {
 
   T = T.getCanonicalType();
   if (T->isDependentType())
-    return PointerAuthContent::None;
+    return PointerAuthContent::ContainsNone;
 
+  PointerAuthContent Result = PointerAuthContent::ContainsNone;
   if (T.hasAddressDiscriminatedPointerAuth())
-    return PointerAuthContent::AddressDiscriminatedData;
+    Result = Result | PointerAuthContent::ContainsAddressDiscriminatedData;
+  if (T->isFunctionPointerType()) {
+    PointerAuthQualifier ExplicitQualifier = T.getPointerAuth();
+    if (!ExplicitQualifier.isPresent() || 
!ExplicitQualifier.isAddressDiscriminated())
+      Result = Result | 
PointerAuthContent::ContainsDefaultAuthenticatedFunction;
+  }
   const RecordDecl *RD = T->getAsRecordDecl();
   if (!RD)
-    return PointerAuthContent::None;
+    return Result;
 
   if (RD->isInvalidDecl())
-    return PointerAuthContent::None;
+    return PointerAuthContent::ContainsNone;
 
   if (auto Existing = RecordContainsAddressDiscriminatedPointerAuth.find(RD);
       Existing != RecordContainsAddressDiscriminatedPointerAuth.end())
     return Existing->second;
 
-  PointerAuthContent Result = PointerAuthContent::None;
-
   auto SaveResultAndReturn = [&]() -> PointerAuthContent {
     auto [ResultIter, DidAdd] =
         RecordContainsAddressDiscriminatedPointerAuth.try_emplace(RD, Result);
@@ -1665,19 +1669,16 @@ ASTContext::findPointerAuthContent(QualType T) const {
     assert(DidAdd);
     return Result;
   };
-  auto ShouldContinueAfterUpdate = [&](PointerAuthContent NewResult) {
-    static_assert(PointerAuthContent::None <
-                  PointerAuthContent::AddressDiscriminatedVTable);
-    static_assert(PointerAuthContent::AddressDiscriminatedVTable <
-                  PointerAuthContent::AddressDiscriminatedData);
-    if (NewResult > Result)
-      Result = NewResult;
-    return Result != PointerAuthContent::AddressDiscriminatedData;
+  auto ShouldContinueAfterUpdate = [&](PointerAuthContent NewFlag) {
+    Result = Result | NewFlag;
+    if ((NewFlag & PointerAuthContent::ContainsAddressDiscriminatedVTable) != 
PointerAuthContent::ContainsNone)
+      Result = Result | PointerAuthContent::ContainsAddressDiscriminatedData;
+    return Result != PointerAuthContent::ContainsAllFlags;
   };
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
     if (primaryBaseHaseAddressDiscriminatedVTableAuthentication(*this, CXXRD) 
&&
         !ShouldContinueAfterUpdate(
-            PointerAuthContent::AddressDiscriminatedVTable))
+            PointerAuthContent::ContainsAddressDiscriminatedVTable))
       return SaveResultAndReturn();
     for (auto Base : CXXRD->bases()) {
       if (!ShouldContinueAfterUpdate(findPointerAuthContent(Base.getType())))

>From d1069b81869e1c49e3dc2ea0a2fcd3ce37843f66 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <[email protected]>
Date: Sat, 13 Dec 2025 15:27:24 -0800
Subject: [PATCH 2/2] not to be actually merged but want to keep the tests
 handy

---
 clang/include/clang/Basic/DiagnosticGroups.td    |  2 +-
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 clang/lib/Sema/Sema.cpp                          |  5 +++++
 clang/lib/Sema/SemaDecl.cpp                      |  7 +++++++
 clang/test/SemaCXX/ptrauth-type-traits.cpp       | 10 +++++++++-
 5 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 16434f9f9dd46..7a9aa80a48148 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1081,7 +1081,7 @@ def GNUZeroLineDirective : 
DiagGroup<"gnu-zero-line-directive">;
 def GNUZeroVariadicMacroArguments : 
DiagGroup<"gnu-zero-variadic-macro-arguments", [VariadicMacroArgumentsOmitted]>;
 def MisleadingIndentation : DiagGroup<"misleading-indentation">;
 def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">;
-def PtrAuthWeakSchema : DiagGroup<"ptrauth-weak-schema">;
+def PtrAuthWeakGlobalSchema : DiagGroup<"ptrauth-weak-global-schema">;
 
 // This covers both the deprecated case (in C++98)
 // and the extension case (in C++11 onwards).
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 46cfdf85e504a..c5326cf3cf717 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1019,7 +1019,7 @@ def err_ptrauth_type_disc_undiscriminated : Error<
   "cannot pass undiscriminated type %0 to "
   "'__builtin_ptrauth_type_discriminator'">;
 def warn_ptrauth_weak_global_function_pointer :
-  Warning<"global pointer %0 uses the default pointer authentication schema">,
+  Warning<"global variable %0 uses the default pointer authentication schema">,
   InGroup<PtrAuthWeakSchema>;
 
 def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index d32d7b960288d..dabcd1596252f 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -994,6 +994,10 @@ void Sema::getUndefinedButUsed(
   }
 }
 
+static void checkQuestionableGlobalFunctionPointers(Sema &S) {
+  
+}
+
 /// checkUndefinedButUsed - Check for undefined objects with internal linkage
 /// or that are inline.
 static void checkUndefinedButUsed(Sema &S) {
@@ -1624,6 +1628,7 @@ void Sema::ActOnEndOfTranslationUnit() {
     TUScope = nullptr;
 
   checkExposure(Context.getTranslationUnitDecl());
+  checkQuestionableGlobalFunctionPointers(*this);
 }
 
 
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 47bd7295e93f6..051245630f854 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15053,6 +15053,13 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl 
*var) {
   // Build the bindings if this is a structured binding declaration.
   if (auto *DD = dyn_cast<DecompositionDecl>(var))
     CheckCompleteDecompositionDeclaration(DD);
+
+  if (GlobalStorage && Context.isPointerAuthenticationAvailable() &&
+      !Diags.isIgnored(diag::warn_ptrauth_weak_global_function_pointer, 
var->getLocation())) {
+    if (Context.containsDefaultAuthenticatedFunctionPointer(var->getType())) {
+      Diag(var->getLocation(), 
diag::warn_ptrauth_weak_global_function_pointer) << var << 
var->getSourceRange();
+    }
+  }
 }
 
 void Sema::CheckStaticLocalForDllExport(VarDecl *VD) {
diff --git a/clang/test/SemaCXX/ptrauth-type-traits.cpp 
b/clang/test/SemaCXX/ptrauth-type-traits.cpp
index a81ef1cce25b6..f4e33802e36f8 100644
--- a/clang/test/SemaCXX/ptrauth-type-traits.cpp
+++ b/clang/test/SemaCXX/ptrauth-type-traits.cpp
@@ -427,7 +427,15 @@ namespace GH159505 {
     static_assert(PTRAUTH_ENABLED != __is_trivially_copyable(Ptr<T>));
   }
 
-  auto f = test<int>;
+  auto * __ptrauth(1,1,1) f = test<int>;
+  void (*__ptrauth(1,0,0) f1)() = test<int>;
+  void (*__ptrauth(1,1,0) f2)() = test<int>;
+  void (*__ptrauth(1,1,1) f3)() = test<int>;
+
+  struct Foo {
+    void (*field)();
+  };
+  Foo object;
   static_assert(!__is_trivially_copyable(B<1>));
   static_assert(PTRAUTH_ENABLED != __is_trivially_copyable(C<1>));
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to