diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2ea3ed759ff42..97700780cf949 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 0000000000000..289d13c79304c --- /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