[clang] [PAC][clang] Fix ptrauth module flags behavior (PR #204226)
Daniil Kovalev via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 18 10:08:07 PDT 2026
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/204226
>From ed37c72a50cbc61eaf083e30dde806a176549712 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 16 Jun 2026 21:43:12 +0300
Subject: [PATCH 1/2] [PAC][clang] Fix ptrauth module flags behavior
The `Error` merge behavior only has effect when module flags values
mismatch, while it allows the flag being present in one module and
absent in another one.
Always emit `ptrauth-elf-got` module flag for AArch64 targets and
`ptrauth-sign-personality` module flag for AArch64 Linux targets.
The value is either 0 or 1.
---
clang/lib/CodeGen/CodeGenModule.cpp | 12 +++++++-----
clang/test/CodeGen/ptrauth-module-flags.c | 12 ++++++++++--
clang/test/CodeGen/ubsan-function-sugared.cpp | 2 +-
clang/test/CodeGen/ubsan-function.cpp | 2 +-
clang/test/CodeGenCXX/pfp-memcpy.cpp | 4 ++--
5 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 41049d85121be..4d38fbdf20536 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1481,13 +1481,15 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Min,
"sign-return-address-with-bkey", 2);
- if (LangOpts.PointerAuthELFGOT)
- getModule().addModuleFlag(llvm::Module::Error, "ptrauth-elf-got", 1);
+ getModule().addModuleFlag(
+ llvm::Module::Error, "ptrauth-elf-got",
+ static_cast<uint32_t>(LangOpts.PointerAuthELFGOT));
if (getTriple().isOSLinux()) {
- if (LangOpts.PointerAuthCalls)
- getModule().addModuleFlag(llvm::Module::Error,
- "ptrauth-sign-personality", 1);
+ getModule().addModuleFlag(
+ llvm::Module::Error, "ptrauth-sign-personality",
+ static_cast<uint32_t>(LangOpts.PointerAuthCalls));
+
assert(getTriple().isOSBinFormatELF());
using namespace llvm::ELF;
uint64_t PAuthABIVersion =
diff --git a/clang/test/CodeGen/ptrauth-module-flags.c b/clang/test/CodeGen/ptrauth-module-flags.c
index 6c175c0aad781..ffe62ec25f655 100644
--- a/clang/test/CodeGen/ptrauth-module-flags.c
+++ b/clang/test/CodeGen/ptrauth-module-flags.c
@@ -4,10 +4,18 @@
// ELFGOT: !llvm.module.flags = !{
// ELFGOT-SAME: !0
+// ELFGOT-SAME: !1
// ELFGOT: !0 = !{i32 1, !"ptrauth-elf-got", i32 1}
+// ELFGOT: !1 = !{i32 1, !"ptrauth-sign-personality", i32 0}
// PERSONALITY: !llvm.module.flags = !{
// PERSONALITY-SAME: !0
-// PERSONALITY: !0 = !{i32 1, !"ptrauth-sign-personality", i32 1}
+// PERSONALITY-SAME: !1
+// PERSONALITY: !0 = !{i32 1, !"ptrauth-elf-got", i32 0}
+// PERSONALITY: !1 = !{i32 1, !"ptrauth-sign-personality", i32 1}
-// OFF-NOT: "ptrauth-
+// OFF: !llvm.module.flags = !{
+// OFF-SAME: !0
+// OFF-SAME: !1
+// OFF: !0 = !{i32 1, !"ptrauth-elf-got", i32 0}
+// OFF: !1 = !{i32 1, !"ptrauth-sign-personality", i32 0}
diff --git a/clang/test/CodeGen/ubsan-function-sugared.cpp b/clang/test/CodeGen/ubsan-function-sugared.cpp
index 308edd8c0cd9b..2a6f8c81d7e0f 100644
--- a/clang/test/CodeGen/ubsan-function-sugared.cpp
+++ b/clang/test/CodeGen/ubsan-function-sugared.cpp
@@ -10,7 +10,7 @@ auto fun() {}
// GNU-LABEL: define{{.*}} void @_Z6callerv()
// MSVC-LABEL: define{{.*}} void @"?caller@@YAXXZ"()
-// ARM: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -2), !nosanitize !5
+// ARM: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -2), !nosanitize
// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
// CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
// CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize
diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp
index 817a9cbefe690..cf419fa5b4753 100644
--- a/clang/test/CodeGen/ubsan-function.cpp
+++ b/clang/test/CodeGen/ubsan-function.cpp
@@ -13,7 +13,7 @@ void fun() {}
// GNU-LABEL: define{{.*}} void @_Z6callerPFvvE(ptr noundef %f)
// MSVC-LABEL: define{{.*}} void @"?caller@@YAXP6AXXZ at Z"(ptr noundef %f)
-// ARM: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -2), !nosanitize !6
+// ARM: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -2), !nosanitize
// AUTH: %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize
// AUTH: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize
// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
diff --git a/clang/test/CodeGenCXX/pfp-memcpy.cpp b/clang/test/CodeGenCXX/pfp-memcpy.cpp
index be746fd8673a0..9621901c5c4c7 100644
--- a/clang/test/CodeGenCXX/pfp-memcpy.cpp
+++ b/clang/test/CodeGenCXX/pfp-memcpy.cpp
@@ -42,7 +42,7 @@ void trivial_copy(ClassWithTrivialCopy *s1) {
// CHECK-NEXT: %a = getelementptr inbounds nuw %struct.ClassWithTrivialCopy, ptr %this1, i32 0, i32 0
// CHECK-NEXT: %1 = ptrtoint ptr %this1 to i64
// CHECK-NEXT: %2 = call ptr @llvm.protected.field.ptr.p0(ptr %a, i64 %1, i1 true) [ "deactivation-symbol"(ptr @__pfp_ds__ZTS20ClassWithTrivialCopy.a) ]
-// CHECK-NEXT: %3 = load ptr, ptr %.addr, align 8, !nonnull !1, !align !2
+// CHECK-NEXT: %3 = load ptr, ptr %.addr, align 8, !nonnull ![[#]], !align ![[#]]
// CHECK-NEXT: %a2 = getelementptr inbounds nuw %struct.ClassWithTrivialCopy, ptr %3, i32 0, i32 0
// CHECK-NEXT: %4 = ptrtoint ptr %3 to i64
// CHECK-NEXT: %5 = call ptr @llvm.protected.field.ptr.p0(ptr %a2, i64 %4, i1 true) [ "deactivation-symbol"(ptr @__pfp_ds__ZTS20ClassWithTrivialCopy.a) ]
@@ -51,7 +51,7 @@ void trivial_copy(ClassWithTrivialCopy *s1) {
// CHECK-NEXT: %c = getelementptr inbounds nuw %struct.ClassWithTrivialCopy, ptr %this1, i32 0, i32 1
// CHECK-NEXT: %7 = ptrtoint ptr %this1 to i64
// CHECK-NEXT: %8 = call ptr @llvm.protected.field.ptr.p0(ptr %c, i64 %7, i1 true) [ "deactivation-symbol"(ptr @__pfp_ds__ZTS20ClassWithTrivialCopy.c) ]
-// CHECK-NEXT: %9 = load ptr, ptr %.addr, align 8, !nonnull !1, !align !2
+// CHECK-NEXT: %9 = load ptr, ptr %.addr, align 8, !nonnull ![[#]], !align ![[#]]
// CHECK-NEXT: %c3 = getelementptr inbounds nuw %struct.ClassWithTrivialCopy, ptr %9, i32 0, i32 1
// CHECK-NEXT: %10 = ptrtoint ptr %9 to i64
// CHECK-NEXT: %11 = call ptr @llvm.protected.field.ptr.p0(ptr %c3, i64 %10, i1 true) [ "deactivation-symbol"(ptr @__pfp_ds__ZTS20ClassWithTrivialCopy.c) ]
>From ba1154796fb6e3374f06c4bc2d5c6c16810ce2bb Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 18 Jun 2026 20:07:32 +0300
Subject: [PATCH 2/2] Address review comments
---
clang/lib/CodeGen/CodeGenModule.cpp | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4d38fbdf20536..2942687bd37a0 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1480,7 +1480,8 @@ void CodeGenModule::Release() {
if (!LangOpts.isSignReturnAddressWithAKey())
getModule().addModuleFlag(llvm::Module::Min,
"sign-return-address-with-bkey", 2);
-
+ }
+ if (T.isAArch64()) {
getModule().addModuleFlag(
llvm::Module::Error, "ptrauth-elf-got",
static_cast<uint32_t>(LangOpts.PointerAuthELFGOT));
@@ -1520,14 +1521,12 @@ void CodeGenModule::Release() {
static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_FPTRTYPEDISCR ==
AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
"Update when new enum items are defined");
- if (PAuthABIVersion != 0) {
- getModule().addModuleFlag(llvm::Module::Error,
- "aarch64-elf-pauthabi-platform",
- AARCH64_PAUTH_PLATFORM_LLVM_LINUX);
- getModule().addModuleFlag(llvm::Module::Error,
- "aarch64-elf-pauthabi-version",
- PAuthABIVersion);
- }
+
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-platform",
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX);
+ getModule().addModuleFlag(
+ llvm::Module::Error, "aarch64-elf-pauthabi-version", PAuthABIVersion);
}
}
if ((T.isARM() || T.isThumb()) && getTriple().isTargetAEABI() &&
More information about the cfe-commits
mailing list