Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -368,6 +368,9 @@ def err_drv_ropi_incompatible_with_cxx : Error< "ROPI is not compatible with c++">; +def err_stack_tagging_requires_hardware_feature : Error< + "'-fsanitize=memtag' requires the v8.5A Memory Tagging Extension (+memtag)">; + def warn_target_unsupported_nan2008 : Warning< "ignoring '-mnan=2008' option because the '%0' architecture does not support it">, InGroup; Index: clang/include/clang/Driver/SanitizerArgs.h =================================================================== --- clang/include/clang/Driver/SanitizerArgs.h +++ clang/include/clang/Driver/SanitizerArgs.h @@ -63,6 +63,7 @@ bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); } + bool needsMemtag() const { return Sanitizers.has(SanitizerKind::MemTag); } bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -1564,7 +1564,8 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); + const ToolChain &TC = getToolChain(); + const llvm::Triple &Triple = TC.getEffectiveTriple(); if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || Args.hasArg(options::OPT_mkernel) || @@ -1601,11 +1602,9 @@ } // Enable/disable return address signing and indirect branch targets. + const Driver &D = TC.getDriver(); if (Arg *A = Args.getLastArg(options::OPT_msign_return_address_EQ, options::OPT_mbranch_protection_EQ)) { - - const Driver &D = getToolChain().getDriver(); - StringRef Scope, Key; bool IndirectBranches; @@ -1628,6 +1627,12 @@ if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); } + + if (TC.getSanitizerArgs().needsMemtag()) { + if (std::find(CmdArgs.begin(), CmdArgs.end(), StringRef("+mte")) == CmdArgs.end()) { + D.Diag(diag::err_stack_tagging_requires_hardware_feature); + } + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, Index: clang/test/Driver/fsanitize.c =================================================================== --- clang/test/Driver/fsanitize.c +++ clang/test/Driver/fsanitize.c @@ -191,6 +191,13 @@ // RUN: %clang -target x86_64-linux-android -fsanitize=memtag -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-BAD-ARCH // CHECK-SANMT-BAD-ARCH: unsupported option '-fsanitize=memtag' for target +// RUN: %clang -target aarch64-linux -fsanitize=memtag -march=armv8-a+memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-MT +// CHECK-SANMT-MT: "-target-feature" "+mte" +// CHECK-SANMT-MT-SAME: "-fsanitize=memtag" + +// RUN: %clang -target aarch64-linux -fsanitize=memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-NOMT +// CHECK-SANMT-NOMT: '-fsanitize=memtag' requires the v8.5A Memory Tagging Extension (+memtag) + // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-after-scope %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE // RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fsanitize-address-use-after-scope -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE // CHECK-USE-AFTER-SCOPE: -cc1{{.*}}-fsanitize-address-use-after-scope