https://github.com/martinuy updated 
https://github.com/llvm/llvm-project/pull/157779

>From 8fe991fb658d02351b2e819b275de1e821075f03 Mon Sep 17 00:00:00 2001
From: Martin Balao Alonso <[email protected]>
Date: Tue, 9 Sep 2025 18:29:38 -0700
Subject: [PATCH 1/3] [clang][ptrauth] Warn about the use of a weak signing
 schema

In this change we added the -Wptrauth-weak-schema diagnostic (enabled by
default on targets that support pointer authentication) to warn about the
use of a weak signing schema for function pointers stored in global variables
with internal linkage.

rdar://159299739
---
 clang/include/clang/Basic/DiagnosticGroups.td |  1 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 ++
 clang/lib/Sema/SemaDecl.cpp                   |  9 +++
 clang/test/Sema/ptrauth-weak-schema.c         | 68 +++++++++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 clang/test/Sema/ptrauth-weak-schema.c

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 0c994e0b5ca4d..de10c39a4ac3c 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1072,6 +1072,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 b0e669cd3560d..e1dc8ab20d6f4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1046,6 +1046,10 @@ def err_ptrauth_address_discrimination_invalid : Error<
 def err_ptrauth_extra_discriminator_invalid : Error<
   "invalid extra discriminator flag '%0'; '__ptrauth' requires a value between 
"
   "'0' and '%1'">;
+def warn_ptrauth_weak_schema
+    : Warning<"internal variable %0 is using a weak signing schema for pointer 
"
+              "authentication">,
+      InGroup<PtrAuthWeakSchema>;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7c1459e320167..a8eb1188916b7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8357,6 +8357,15 @@ NamedDecl *Sema::ActOnVariableDeclarator(
                                    D.isFunctionDefinition());
   }
 
+  // Warn about the use of a weak pointer authentication schema on a variable
+  // with internal linkage.
+  if (getLangOpts().PointerAuthCalls && NewVD->isFunctionPointerType() &&
+      !isExternallyVisible(NewVD->getLinkageInternal())) {
+    PointerAuthQualifier Q = NewVD->getType().getQualifiers().getPointerAuth();
+    if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0))
+      Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema) << NewVD;
+  }
+
   if (NewTemplate) {
     if (NewVD->isInvalidDecl())
       NewTemplate->setInvalidDecl();
diff --git a/clang/test/Sema/ptrauth-weak-schema.c 
b/clang/test/Sema/ptrauth-weak-schema.c
new file mode 100644
index 0000000000000..792ff9f99627c
--- /dev/null
+++ b/clang/test/Sema/ptrauth-weak-schema.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls 
-fptrauth-intrinsics -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64e-apple-ios -DNO_PTRAUTH -fsyntax-only -verify 
%s
+
+#if defined(NO_PTRAUTH)
+
+#define FN_PTR_AUTH(address_diversity, constant_discriminator)
+// expected-no-diagnostics
+
+#else // !defined(NO_PTRAUTH)
+
+#if !__has_extension(ptrauth_qualifier)
+#error __ptrauth qualifier not enabled
+#endif
+
+#include <ptrauth.h>
+
+#define FN_PTR_AUTH(address_diversity, constant_discriminator) \
+  __ptrauth(ptrauth_key_function_pointer, address_diversity, 
constant_discriminator)
+
+#endif // defined(NO_PTRAUTH)
+
+// Global variables with external linkage and weak pointer authentication 
should
+// not raise any warning.
+extern void(* g1_external_weak)(void);
+void(* FN_PTR_AUTH(0, 0) g2_external_weak)(void);
+
+// Global variables with internal linkage and strong pointer authentication
+// should not raise any warning.
+static void(* FN_PTR_AUTH(1, 65535) g1_internal_strong)(void);
+static void(* FN_PTR_AUTH(0, 65535) g2_internal_strong)(void);
+static void(* FN_PTR_AUTH(1, 0) g3_internal_strong)(void);
+
+#if !defined(NO_PTRAUTH)
+// Global variables with internal linkage and weak pointer authentication 
should
+// raise a warning.
+static void(* g1_internal_weak)(void);
+// expected-warning@-1 {{internal variable 'g1_internal_weak' is using a weak 
signing schema for pointer authentication}}
+static void(* FN_PTR_AUTH(0, 0) g2_internal_weak)(void);
+// expected-warning@-1 {{internal variable 'g2_internal_weak' is using a weak 
signing schema for pointer authentication}}
+
+// Assert that -Wptrauth-weak-schema silences warnings.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wptrauth-weak-schema"
+static void(* g3_internal_weak)(void);
+#pragma clang diagnostic pop
+#endif
+
+void test_local_variables(void) {
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wunused-variable"
+
+    #if !defined(NO_PTRAUTH)
+    // Local variables (internal linkage) with weak pointer authentication
+    // should raise a warning.
+    static void(* l1_internal_weak)(void);
+    // expected-warning@-1 {{internal variable 'l1_internal_weak' is using a 
weak signing schema for pointer authentication}}
+    static void(* FN_PTR_AUTH(0, 0) l2_internal_weak)(void);
+    // expected-warning@-1 {{internal variable 'l2_internal_weak' is using a 
weak signing schema for pointer authentication}}
+    #endif
+
+    // Local variables (internal linkage) with strong pointer authentication
+    // should not raise any warning.
+    void(* FN_PTR_AUTH(1, 65535) l1_internal_strong)(void);
+    void(* FN_PTR_AUTH(0, 65535) l2_internal_strong)(void);
+    void(* FN_PTR_AUTH(1, 0) l3_internal_strong)(void);
+
+    #pragma clang diagnostic pop
+}

>From bc4d0a78e74b86b2ae490d8b7a3428a65fa66ece Mon Sep 17 00:00:00 2001
From: Martin Balao Alonso <[email protected]>
Date: Wed, 10 Sep 2025 16:10:29 -0700
Subject: [PATCH 2/3] Changes after @ojhunt's review on 2025-09-09 (#157779)

---
 clang/include/clang/AST/ASTContext.h          |  9 ++---
 clang/include/clang/Basic/DiagnosticGroups.td |  1 -
 .../clang/Basic/DiagnosticSemaKinds.td        |  7 ++--
 clang/lib/Sema/SemaDecl.cpp                   | 10 +++---
 clang/test/Sema/ptrauth-weak-schema.c         | 34 ++++++-------------
 5 files changed, 26 insertions(+), 35 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 1c17333b722f8..1580968e857d7 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -659,6 +659,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
     return findPointerAuthContent(T) != PointerAuthContent::None;
   }
 
+  // A simple helper function to short circuit pointer auth checks.
+  bool isPointerAuthenticationAvailable() const {
+    return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
+  }
+
 private:
   llvm::DenseMap<const CXXRecordDecl *, CXXRecordDeclRelocationInfo>
       RelocatableClasses;
@@ -670,10 +675,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
     AddressDiscriminatedData
   };
 
-  // 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 de10c39a4ac3c..0c994e0b5ca4d 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1072,7 +1072,6 @@ 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 e1dc8ab20d6f4..35bedc9349686 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1047,9 +1047,10 @@ def err_ptrauth_extra_discriminator_invalid : Error<
   "invalid extra discriminator flag '%0'; '__ptrauth' requires a value between 
"
   "'0' and '%1'">;
 def warn_ptrauth_weak_schema
-    : Warning<"internal variable %0 is using a weak signing schema for pointer 
"
-              "authentication">,
-      InGroup<PtrAuthWeakSchema>;
+    : Warning<"%0 has internal linkage with a %select{|default }1"
+              "pointer authentication schema that should be overridden by "
+              "%select{a|an explicit}1 schema with unique diversifiers">,
+      InGroup<DiagGroup<"ptrauth-weak-schema">>;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a8eb1188916b7..7a7abf1c4b627 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8359,11 +8359,13 @@ NamedDecl *Sema::ActOnVariableDeclarator(
 
   // Warn about the use of a weak pointer authentication schema on a variable
   // with internal linkage.
-  if (getLangOpts().PointerAuthCalls && NewVD->isFunctionPointerType() &&
-      !isExternallyVisible(NewVD->getLinkageInternal())) {
+  if (Context.isPointerAuthenticationAvailable() &&
+      NewVD->isFunctionPointerType() && !NewVD->isExternallyVisible()) {
     PointerAuthQualifier Q = NewVD->getType().getQualifiers().getPointerAuth();
-    if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0))
-      Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema) << NewVD;
+    if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0)) 
{
+      Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema)
+          << NewVD << (Q ? 0 : 1);
+    }
   }
 
   if (NewTemplate) {
diff --git a/clang/test/Sema/ptrauth-weak-schema.c 
b/clang/test/Sema/ptrauth-weak-schema.c
index 792ff9f99627c..e0aa89efc47ab 100644
--- a/clang/test/Sema/ptrauth-weak-schema.c
+++ b/clang/test/Sema/ptrauth-weak-schema.c
@@ -1,23 +1,16 @@
-// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls 
-fptrauth-intrinsics -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple arm64e-apple-ios -DNO_PTRAUTH -fsyntax-only -verify 
%s
+// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls 
-fptrauth-intrinsics -fsyntax-only -Wno-unused-variable -verify %s
+// RUN: %clang_cc1 -triple arm64e-apple-ios -DNO_PTRAUTH -fsyntax-only 
-Wno-unused-variable -verify=noptrauth %s
 
-#if defined(NO_PTRAUTH)
-
-#define FN_PTR_AUTH(address_diversity, constant_discriminator)
-// expected-no-diagnostics
-
-#else // !defined(NO_PTRAUTH)
-
-#if !__has_extension(ptrauth_qualifier)
-#error __ptrauth qualifier not enabled
-#endif
+// noptrauth-no-diagnostics
 
 #include <ptrauth.h>
 
+#if defined(NO_PTRAUTH)
+#define FN_PTR_AUTH(address_diversity, constant_discriminator)
+#else
 #define FN_PTR_AUTH(address_diversity, constant_discriminator) \
   __ptrauth(ptrauth_key_function_pointer, address_diversity, 
constant_discriminator)
-
-#endif // defined(NO_PTRAUTH)
+#endif
 
 // Global variables with external linkage and weak pointer authentication 
should
 // not raise any warning.
@@ -34,9 +27,9 @@ static void(* FN_PTR_AUTH(1, 0) g3_internal_strong)(void);
 // Global variables with internal linkage and weak pointer authentication 
should
 // raise a warning.
 static void(* g1_internal_weak)(void);
-// expected-warning@-1 {{internal variable 'g1_internal_weak' is using a weak 
signing schema for pointer authentication}}
+// expected-warning@-1 {{'g1_internal_weak' has internal linkage with a 
default pointer authentication schema that should be overridden by an explicit 
schema with unique diversifiers}}
 static void(* FN_PTR_AUTH(0, 0) g2_internal_weak)(void);
-// expected-warning@-1 {{internal variable 'g2_internal_weak' is using a weak 
signing schema for pointer authentication}}
+// expected-warning@-1 {{'g2_internal_weak' has internal linkage with a 
pointer authentication schema that should be overridden by a schema with unique 
diversifiers}}
 
 // Assert that -Wptrauth-weak-schema silences warnings.
 #pragma clang diagnostic push
@@ -46,16 +39,13 @@ static void(* g3_internal_weak)(void);
 #endif
 
 void test_local_variables(void) {
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wunused-variable"
-
     #if !defined(NO_PTRAUTH)
     // Local variables (internal linkage) with weak pointer authentication
     // should raise a warning.
     static void(* l1_internal_weak)(void);
-    // expected-warning@-1 {{internal variable 'l1_internal_weak' is using a 
weak signing schema for pointer authentication}}
+    // expected-warning@-1 {{'l1_internal_weak' has internal linkage with a 
default pointer authentication schema that should be overridden by an explicit 
schema with unique diversifiers}}
     static void(* FN_PTR_AUTH(0, 0) l2_internal_weak)(void);
-    // expected-warning@-1 {{internal variable 'l2_internal_weak' is using a 
weak signing schema for pointer authentication}}
+    // expected-warning@-1 {{'l2_internal_weak' has internal linkage with a 
pointer authentication schema that should be overridden by a schema with unique 
diversifiers}}
     #endif
 
     // Local variables (internal linkage) with strong pointer authentication
@@ -63,6 +53,4 @@ void test_local_variables(void) {
     void(* FN_PTR_AUTH(1, 65535) l1_internal_strong)(void);
     void(* FN_PTR_AUTH(0, 65535) l2_internal_strong)(void);
     void(* FN_PTR_AUTH(1, 0) l3_internal_strong)(void);
-
-    #pragma clang diagnostic pop
 }

>From 1d90050dce1de92876d1f9a4be62acf7090c7483 Mon Sep 17 00:00:00 2001
From: Martin Balao Alonso <[email protected]>
Date: Wed, 10 Sep 2025 19:22:29 -0700
Subject: [PATCH 3/3] fixup! Changes after @ojhunt's review on 2025-09-09
 (#157779)

Changes after @ojhunt's review on 2025-09-10 (#157779)
---
 clang/lib/Sema/SemaDecl.cpp           | 3 +--
 clang/test/Sema/ptrauth-weak-schema.c | 4 ++++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7a7abf1c4b627..60410c05d10cb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8363,8 +8363,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
       NewVD->isFunctionPointerType() && !NewVD->isExternallyVisible()) {
     PointerAuthQualifier Q = NewVD->getType().getQualifiers().getPointerAuth();
     if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0)) 
{
-      Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema)
-          << NewVD << (Q ? 0 : 1);
+      Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema) << NewVD << 
!Q;
     }
   }
 
diff --git a/clang/test/Sema/ptrauth-weak-schema.c 
b/clang/test/Sema/ptrauth-weak-schema.c
index e0aa89efc47ab..f7f10be07736e 100644
--- a/clang/test/Sema/ptrauth-weak-schema.c
+++ b/clang/test/Sema/ptrauth-weak-schema.c
@@ -5,6 +5,10 @@
 
 #include <ptrauth.h>
 
+#if defined(__PTRAUTH__) == defined(NO_PTRAUTH)
+#error expected pointer authentication state does not match actual
+#endif
+
 #if defined(NO_PTRAUTH)
 #define FN_PTR_AUTH(address_diversity, constant_discriminator)
 #else

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

Reply via email to