diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 195a61127c2a6..cd72e254ea3b1 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -338,6 +338,8 @@ def err_target_unsupported_mcmse : Error< "-mcmse is not supported for %0">; def err_opt_not_valid_with_opt : Error< "option '%0' cannot be specified with '%1'">; +def err_opt_not_valid_with_opt_on_target : Error< + "option '%0' cannot be specified with '%1' for the %2 sub-architecture">; def err_opt_not_valid_without_opt : Error< "option '%0' cannot be specified without '%1'">; def err_opt_not_valid_on_target : Error< diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index dad1e9e5bd330..bb66db5feae8c 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -847,7 +847,13 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 && llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M) D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName(); - else if (Arg *B = Args.getLastArg(options::OPT_mno_movt)) + else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) { + if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi, + options::OPT_fpic, options::OPT_fpie, + options::OPT_fPIC, options::OPT_fPIE)) + D.Diag(diag::err_opt_not_valid_with_opt_on_target) + << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName(); + } else if (Arg *B = Args.getLastArg(options::OPT_mno_movt)) D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args); Features.push_back("+execute-only"); diff --git a/clang/test/Driver/arm-execute-only.c b/clang/test/Driver/arm-execute-only.c index 1b2fad7299484..a9bf1656fd27e 100644 --- a/clang/test/Driver/arm-execute-only.c +++ b/clang/test/Driver/arm-execute-only.c @@ -20,3 +20,27 @@ // RUN: not %clang -### --target=arm-arm-none-eabi -march=armv8-m.main -mpure-code -mno-movt %s 2>&1 \ // RUN: | FileCheck %s -check-prefix CHECK-PURE-CODE-NO-MOVT // CHECK-PURE-CODE-NO-MOVT: error: option '-mpure-code' cannot be specified with '-mno-movt' + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -fropi %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ROPI +// CHECK-NO-EXECUTE-ROPI: error: option '-mexecute-only' cannot be specified with '-fropi' for the thumbv6m sub-architecture + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -frwpi %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-RWPI +// CHECK-NO-EXECUTE-RWPI: error: option '-mexecute-only' cannot be specified with '-frwpi' for the thumbv6m sub-architecture + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -fpic %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-PIC +// CHECK-NO-EXECUTE-PIC: error: option '-mexecute-only' cannot be specified with '-fpic' for the thumbv6m sub-architecture + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -fpie %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-PIE +// CHECK-NO-EXECUTE-PIE: error: option '-mexecute-only' cannot be specified with '-fpie' for the thumbv6m sub-architecture + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -fPIC %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-PIC2 +// CHECK-NO-EXECUTE-PIC2: error: option '-mexecute-only' cannot be specified with '-fPIC' for the thumbv6m sub-architecture + +// RUN: not %clang -### --target=arm-arm-none-eabi -march=armv6-m -mexecute-only -fPIE %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-PIE2 +// CHECK-NO-EXECUTE-PIE2: error: option '-mexecute-only' cannot be specified with '-fPIE' for the thumbv6m sub-architecture