aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Hunt <oliver@apple.com>2025-08-13 15:00:00 -0700
committerOliver Hunt <oliver@apple.com>2025-08-13 15:33:34 -0700
commitd93cc44be8e45c117fef0238555c58eddb658782 (patch)
treec389f9ece8b140077620b3132b3657f2f6d876be
parentf9b9e9b7d52219842fb4386ee802762f83f2fabd (diff)
downloadllvm-users/ojhunt/pedantic-errors-incompatible-with-arm64e.zip
llvm-users/ojhunt/pedantic-errors-incompatible-with-arm64e.tar.gz
llvm-users/ojhunt/pedantic-errors-incompatible-with-arm64e.tar.bz2
[clang][PAC] Disallow -pedantic-errors in conjunction with pointer authenticationusers/ojhunt/pedantic-errors-incompatible-with-arm64e
The __has_extension query for the __ptrauth qualifier returns false when -pedantic-errors is specified by the developer, which results in ABI mismatches and potentially ODR violations as well. The only way to resolve this is to to make it an error to attempt to use the -pedantic-errors option when targeting a platform where pointer authentication is present. This may cause compilation issues for some projects but is better than bad codegen.
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp58
-rw-r--r--clang/test/Driver/aarch64-ptrauth-pedantic-errors.c33
2 files changed, 71 insertions, 20 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2ea3ed7..9770078 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3602,30 +3602,43 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
- Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
- Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
- Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
- Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
- Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
- Opts.PointerAuthVTPtrAddressDiscrimination =
- Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
- Opts.PointerAuthVTPtrTypeDiscrimination =
- Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
- Opts.PointerAuthTypeInfoVTPtrDiscrimination =
- Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
- Opts.PointerAuthFunctionTypeDiscrimination =
- Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
- Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
+ const Arg *PedanticErrors = Args.getLastArgNoClaim(OPT_pedantic_errors);
+ auto GetAndCheckPointerAuthArg = [&](driver::options::ID Option) {
+ Arg *OptionArg = Args.getLastArg(Option);
+ if (OptionArg && PedanticErrors) {
+ Diags.Report(diag::err_drv_incompatible_options)
+ << OptionArg->getSpelling() << PedanticErrors->getSpelling();
+ }
+ return OptionArg != nullptr;
+ };
+ Opts.PointerAuthIntrinsics =
+ GetAndCheckPointerAuthArg(OPT_fptrauth_intrinsics);
+ Opts.PointerAuthCalls = GetAndCheckPointerAuthArg(OPT_fptrauth_calls);
+ Opts.PointerAuthReturns = GetAndCheckPointerAuthArg(OPT_fptrauth_returns);
+ Opts.PointerAuthIndirectGotos =
+ GetAndCheckPointerAuthArg(OPT_fptrauth_indirect_gotos);
+ Opts.PointerAuthAuthTraps =
+ GetAndCheckPointerAuthArg(OPT_fptrauth_auth_traps);
+ Opts.PointerAuthVTPtrAddressDiscrimination = GetAndCheckPointerAuthArg(
+ OPT_fptrauth_vtable_pointer_address_discrimination);
+ Opts.PointerAuthVTPtrTypeDiscrimination = GetAndCheckPointerAuthArg(
+ OPT_fptrauth_vtable_pointer_type_discrimination);
+ Opts.PointerAuthTypeInfoVTPtrDiscrimination = GetAndCheckPointerAuthArg(
+ OPT_fptrauth_type_info_vtable_pointer_discrimination);
+ Opts.PointerAuthFunctionTypeDiscrimination = GetAndCheckPointerAuthArg(
+ OPT_fptrauth_function_pointer_type_discrimination);
+ Opts.PointerAuthInitFini = GetAndCheckPointerAuthArg(OPT_fptrauth_init_fini);
Opts.PointerAuthInitFiniAddressDiscrimination =
- Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
- Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
+ GetAndCheckPointerAuthArg(OPT_fptrauth_init_fini_address_discrimination);
+ Opts.PointerAuthELFGOT = GetAndCheckPointerAuthArg(OPT_fptrauth_elf_got);
Opts.AArch64JumpTableHardening =
- Args.hasArg(OPT_faarch64_jump_table_hardening);
+ GetAndCheckPointerAuthArg(OPT_faarch64_jump_table_hardening);
- Opts.PointerAuthObjcIsa = Args.hasArg(OPT_fptrauth_objc_isa);
- Opts.PointerAuthObjcClassROPointers = Args.hasArg(OPT_fptrauth_objc_class_ro);
+ Opts.PointerAuthObjcIsa = GetAndCheckPointerAuthArg(OPT_fptrauth_objc_isa);
+ Opts.PointerAuthObjcClassROPointers =
+ GetAndCheckPointerAuthArg(OPT_fptrauth_objc_class_ro);
Opts.PointerAuthObjcInterfaceSel =
- Args.hasArg(OPT_fptrauth_objc_interface_sel);
+ GetAndCheckPointerAuthArg(OPT_fptrauth_objc_interface_sel);
if (Opts.PointerAuthObjcInterfaceSel)
Opts.PointerAuthObjcInterfaceSelKey =
@@ -5021,6 +5034,11 @@ bool CompilerInvocation::CreateFromArgsImpl(
InputKind DashX = Res.getFrontendOpts().DashX;
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
llvm::Triple T(Res.getTargetOpts().Triple);
+ if (const Arg *PedanticErrors = Args.getLastArgNoClaim(OPT_pedantic_errors);
+ PedanticErrors && T.isArm64e()) {
+ Diags.Report(diag::err_drv_unsupported_opt_for_target)
+ << PedanticErrors->getSpelling() << T.str();
+ }
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
Res.getFileSystemOpts().WorkingDir);
if (Res.getFrontendOpts().GenReducedBMI ||
diff --git a/clang/test/Driver/aarch64-ptrauth-pedantic-errors.c b/clang/test/Driver/aarch64-ptrauth-pedantic-errors.c
new file mode 100644
index 0000000..289d13c
--- /dev/null
+++ b/clang/test/Driver/aarch64-ptrauth-pedantic-errors.c
@@ -0,0 +1,33 @@
+// REQUIRES: aarch64-registered-target
+
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-intrinsics %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-calls %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-returns %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-indirect-gotos %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-auth-traps %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-vtable-pointer-address-discrimination %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-vtable-pointer-type-discrimination %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-function-pointer-type-discrimination %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-init-fini %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-init-fini-address-discrimination %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -faarch64-jump-table-hardening %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-objc-isa %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-objc-class-ro %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=aarch64 -fptrauth-objc-interface-sel %s -c 2>&1 | FileCheck %s
+// RUN: not %clang -pedantic-errors --target=arm64e %s -c 2>&1 | FileCheck %s --check-prefix ARM64E_TRIPLE
+// RUN: not %clang -pedantic-errors --target=arm64e-apple-macosx10.0 %s -c 2>&1 | FileCheck %s --check-prefix ARM64E_MACOS_TRIPLE
+// RUN: not %clang -pedantic-errors -arch arm64e %s -c 2>&1 | FileCheck %s --check-prefix ARM64E_ARCH
+
+// FIXME: Cannot work out what the correct invocation to permit -fptrauth-elf-got is
+// -- not %clang -pedantic-errors --target=aarch64 -fptrauth-elf-got %s -c 2>&1 | FileCheck %s
+
+int i;
+
+// CHECK: error: the combination of '{{.*}}' and '-pedantic-errors' is incompatible
+// ARM64E_TRIPLE: error: unsupported option '-pedantic-errors' for target 'arm64e'
+// ARM64E_MACOS_TRIPLE: error: unsupported option '-pedantic-errors' for target 'arm64e-apple-macosx10.0.0'
+
+// We have a trailing 'arm64e with no closing ' as the full triple is inferred from the host
+// which we don't care about, and don't want to specify as we're wanting to ensure that *just*
+// using '-arch arm64e' is sufficient
+// ARM64E_ARCH: error: unsupported option '-pedantic-errors' for target 'arm64e \ No newline at end of file