Index: include/clang/Basic/Sanitizers.def =================================================================== --- include/clang/Basic/Sanitizers.def +++ include/clang/Basic/Sanitizers.def @@ -44,6 +44,8 @@ // Kernel AddressSanitizer (KASan) SANITIZER("kernel-address", KernelAddress) +SANITIZER("hwaddress", HWAddress) + // MemorySanitizer SANITIZER("memory", Memory) Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -55,12 +55,14 @@ bool needsSharedRt() const { return SharedRuntime; } bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); } + bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); } bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } bool needsLsanRt() const { return Sanitizers.has(SanitizerKind::Leak) && - !Sanitizers.has(SanitizerKind::Address); + !Sanitizers.has(SanitizerKind::Address) && + !Sanitizers.has(SanitizerKind::HWAddress); } bool needsUbsanRt() const; bool requiresMinimalRuntime() const { return MinimalRuntime; } Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -237,6 +237,11 @@ /*Recover*/true)); } +static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createHWAddressSanitizerPass()); +} + static void addMemorySanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { const PassManagerBuilderWrapper &BuilderWrapper = @@ -556,6 +561,13 @@ addKernelAddressSanitizerPasses); } + if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addHWAddressSanitizerPasses); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addHWAddressSanitizerPasses); + } + if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -324,6 +324,10 @@ !isInSanitizerBlacklist(SanitizerKind::KernelAddress, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeAddress); + if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) && + !isInSanitizerBlacklist(SanitizerKind::HWAddress, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); + if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -846,6 +846,8 @@ // Apply sanitizer attributes to the function. if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) Fn->addFnAttr(llvm::Attribute::SanitizeAddress); + if (SanOpts.hasOneOf(SanitizerKind::HWAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); if (SanOpts.has(SanitizerKind::Memory)) Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1582,7 +1582,7 @@ StringRef Category) const { // For now globals can be blacklisted only in ASan and KASan. const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask & - (SanitizerKind::Address | SanitizerKind::KernelAddress); + (SanitizerKind::Address | SanitizerKind::KernelAddress | SanitizerKind::HWAddress); if (!EnabledAsanMask) return false; const auto &SanitizerBL = getContext().getSanitizerBlacklist(); Index: lib/CodeGen/SanitizerMetadata.cpp =================================================================== --- lib/CodeGen/SanitizerMetadata.cpp +++ lib/CodeGen/SanitizerMetadata.cpp @@ -26,7 +26,8 @@ QualType Ty, bool IsDynInit, bool IsBlacklisted) { if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress)) + SanitizerKind::KernelAddress | + SanitizerKind::HWAddress)) return; IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init"); IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty); @@ -58,7 +59,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, bool IsDynInit) { if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress)) + SanitizerKind::KernelAddress | + SanitizerKind::HWAddress)) return; std::string QualName; llvm::raw_string_ostream OS(QualName); @@ -76,7 +78,8 @@ // For now, just make sure the global is not modified by the ASan // instrumentation. if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress)) + SanitizerKind::KernelAddress | + SanitizerKind::HWAddress)) reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true); } Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -31,9 +31,10 @@ NotAllowedWithTrap = Vptr, NotAllowedWithMinimalRuntime = Vptr, RequiresPIE = DataFlow | Scudo, - NeedsUnwindTables = Address | Thread | Memory | DataFlow, - SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined | - Integer | Nullability | DataFlow | Fuzzer | FuzzerNoLink, + NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow, + SupportsCoverage = Address | HWAddress | KernelAddress | Memory | Leak | + Undefined | Integer | Nullability | DataFlow | Fuzzer | + FuzzerNoLink, RecoverableByDefault = Undefined | Integer | Nullability, Unrecoverable = Unreachable | Return, LegacyFsanitizeRecoverMask = Undefined | Integer, @@ -96,6 +97,8 @@ const char *BlacklistFile = nullptr; if (Kinds & Address) BlacklistFile = "asan_blacklist.txt"; + else if (Kinds & HWAddress) + BlacklistFile = "hwasan_blacklist.txt"; else if (Kinds & Memory) BlacklistFile = "msan_blacklist.txt"; else if (Kinds & Thread) @@ -172,8 +175,8 @@ bool SanitizerArgs::needsUbsanRt() const { // All of these include ubsan. - if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() || - needsLsanRt() || needsCfiDiagRt() || needsScudoRt()) + if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() || + needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() || needsScudoRt()) return false; return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || @@ -373,11 +376,12 @@ std::make_pair(Address, Thread | Memory), std::make_pair(Thread, Memory), std::make_pair(Leak, Thread | Memory), - std::make_pair(KernelAddress, Address| Leak | Thread | Memory), - std::make_pair(Efficiency, Address | Leak | Thread | Memory | - KernelAddress), - std::make_pair(Scudo, Address | Leak | Thread | Memory | KernelAddress | - Efficiency) }; + std::make_pair(KernelAddress, Address | Leak | Thread | Memory), + std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress), + std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory | + KernelAddress), + std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory | + KernelAddress | Efficiency)}; for (auto G : IncompatibleGroups) { SanitizerMask Group = G.first; if (Kinds & Group) { Index: lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- lib/Driver/ToolChains/CommonArgs.cpp +++ lib/Driver/ToolChains/CommonArgs.cpp @@ -575,6 +575,8 @@ } if (SanArgs.needsScudoRt()) SharedRuntimes.push_back("scudo"); + if (SanArgs.needsHwasanRt()) + SharedRuntimes.push_back("hwasan"); } // The stats_client library is also statically linked into DSOs. @@ -591,6 +593,12 @@ if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("asan_cxx"); } + + if (SanArgs.needsHwasanRt()) { + StaticRuntimes.push_back("hwasan"); + if (SanArgs.linkCXXRuntimes()) + StaticRuntimes.push_back("hwasan_cxx"); + } if (SanArgs.needsDfsanRt()) StaticRuntimes.push_back("dfsan"); if (SanArgs.needsLsanRt()) Index: lib/Driver/ToolChains/Linux.cpp =================================================================== --- lib/Driver/ToolChains/Linux.cpp +++ lib/Driver/ToolChains/Linux.cpp @@ -854,6 +854,8 @@ Res |= SanitizerKind::Function; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch) Res |= SanitizerKind::Scudo; + if (IsAArch64) + Res |= SanitizerKind::HWAddress; return Res; } Index: lib/Lex/PPMacroExpansion.cpp =================================================================== --- lib/Lex/PPMacroExpansion.cpp +++ lib/Lex/PPMacroExpansion.cpp @@ -1099,6 +1099,8 @@ .Case("address_sanitizer", LangOpts.Sanitize.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) + .Case("hwaddress_sanitizer", + LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress)) .Case("assume_nonnull", true) .Case("attribute_analyzer_noreturn", true) .Case("attribute_availability", true) @@ -1136,7 +1138,8 @@ .Case("nullability_on_arrays", true) .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory)) .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread)) - .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow)) + .Case("dataflow_sanitizer", + LangOpts.Sanitize.has(SanitizerKind::DataFlow)) .Case("efficiency_sanitizer", LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) .Case("scudo", LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) Index: test/CodeGen/address-safety-attr-kasan-hwasan.cpp =================================================================== --- test/CodeGen/address-safety-attr-kasan-hwasan.cpp +++ test/CodeGen/address-safety-attr-kasan-hwasan.cpp @@ -0,0 +1,53 @@ +// Make sure the sanitize_address attribute is emitted when using both ASan and KASan. +// Also document that __attribute__((no_sanitize_address)) doesn't disable KASan instrumentation. + +/// RUN: %clang_cc1 -triple i386-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NOASAN %s +/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=address -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-ASAN %s +/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=kernel-address -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-KASAN %s +/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=hwaddress -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-HWASAN %s + +int HasSanitizeAddress() { + return 1; +} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address +// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address +// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress + +__attribute__((no_sanitize("address"))) +int NoSanitizeQuoteAddress() { + return 0; +} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}} + +__attribute__((no_sanitize_address)) +int NoSanitizeAddress() { + return 0; +} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}} + +__attribute__((no_sanitize("kernel-address"))) +int NoSanitizeKernelAddress() { + return 0; +} + +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}} + +__attribute__((no_sanitize("hwaddress"))) +int NoSanitizeHWAddress() { + return 0; +} + +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}} Index: test/Driver/asan.c =================================================================== --- test/Driver/asan.c +++ test/Driver/asan.c @@ -6,8 +6,13 @@ // RUN: %clang -O1 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN // RUN: %clang -O2 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN // RUN: %clang -O3 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN +// RUN: %clang -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN +// RUN: %clang -O1 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN +// RUN: %clang -O2 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN +// RUN: %clang -O3 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN // Verify that -fsanitize={address,kernel-address} invoke ASan and KASan instrumentation. int foo(int *a) { return *a; } // CHECK-ASAN: __asan_init // CHECK-KASAN: __asan_load4_noabort +// CHECK-HWASAN: __hwasan_init Index: test/Driver/fsanitize-blacklist.c =================================================================== --- test/Driver/fsanitize-blacklist.c +++ test/Driver/fsanitize-blacklist.c @@ -13,6 +13,7 @@ // RUN: echo "badline" > %t.bad // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST // CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.good" "-fsanitize-blacklist={{.*}}.second // Now, check for -fdepfile-entry flags. @@ -20,8 +21,10 @@ // CHECK-BLACKLIST2: -fdepfile-entry={{.*}}.good" "-fdepfile-entry={{.*}}.second // Check that the default blacklist is not added as an extra dependency. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST --implicit-check-not=fdepfile-entry -// CHECK-DEFAULT-BLACKLIST: -fsanitize-blacklist={{.*}}asan_blacklist.txt +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST-ASAN --implicit-check-not=fdepfile-entry +// CHECK-DEFAULT-BLACKLIST-ASAN: -fsanitize-blacklist={{.*}}/asan_blacklist.txt +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST-HWASAN --implicit-check-not=fdepfile-entry +// CHECK-DEFAULT-BLACKLIST-HWASAN: -fsanitize-blacklist={{.*}}/hwasan_blacklist.txt // RUN: %clang -target x86_64-linux-gnu -fsanitize=integer -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry // RUN: %clang -target x86_64-linux-gnu -fsanitize=nullability -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry Index: test/Driver/fsanitize-coverage.c =================================================================== --- test/Driver/fsanitize-coverage.c +++ test/Driver/fsanitize-coverage.c @@ -6,6 +6,7 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -85,6 +85,15 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANKA-SANA // CHECK-SANKA-SANA: '-fsanitize=kernel-address' not allowed with '-fsanitize=address' +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,thread -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANT +// CHECK-SANHA-SANT: '-fsanitize=hwaddress' not allowed with '-fsanitize=thread' + +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANM +// CHECK-SANHA-SANM: '-fsanitize=hwaddress' not allowed with '-fsanitize=memory' + +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANA +// CHECK-SANHA-SANA: '-fsanitize=hwaddress' not allowed with '-fsanitize=address' + // RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANKA-SANL // CHECK-SANKA-SANL: '-fsanitize=kernel-address' not allowed with '-fsanitize=leak' @@ -464,6 +473,9 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize-trap=address -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TRAP // CHECK-ASAN-TRAP: error: unsupported argument 'address' to option '-fsanitize-trap' +// RUN: %clang -target aarch64-linux-gnu -fsanitize-trap=hwaddress -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-TRAP +// CHECK-HWASAN-TRAP: error: unsupported argument 'hwaddress' to option '-fsanitize-trap' + // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.7 -flto -fsanitize=cfi-vcall -fno-sanitize-trap=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-OLD-MACOS // CHECK-CFI-NOTRAP-OLD-MACOS: error: unsupported option '-fno-sanitize-trap=cfi-vcall' for target 'x86_64-apple-darwin10' @@ -595,6 +607,8 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-UBSAN-MINIMAL // CHECK-ASAN-UBSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address' +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-MINIMAL +// CHECK-HWASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=hwaddress' // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-MINIMAL // CHECK-CFI-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall" @@ -634,3 +648,8 @@ // CHECK-SCUDO-MSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=memory' // RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-TSAN // CHECK-SCUDO-TSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=thread' +// RUN: %clang -target aarch64-linux-gnu -fsanitize=scudo,hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-HWASAN +// CHECK-SCUDO-HWASAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=hwaddress' + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-X86_64 +// CHECK-SANHA-X86_64: unsupported option '-fsanitize=hwaddress' for target Index: test/Driver/sanitize_unwind_tables.c =================================================================== --- test/Driver/sanitize_unwind_tables.c +++ test/Driver/sanitize_unwind_tables.c @@ -9,5 +9,7 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow %s -### 2>&1 | FileCheck %s // RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s // RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s +// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s +// RUN: %clang -target aarch64-linux-android -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s // CHECK: -munwind-tables Index: test/Driver/sanitizer-ld.c =================================================================== --- test/Driver/sanitizer-ld.c +++ test/Driver/sanitizer-ld.c @@ -694,3 +694,56 @@ // CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++" // CHECK-SCUDO-ANDROID-STATIC: "-lpthread" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-HWASAN-LINUX %s +// +// CHECK-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-HWASAN-LINUX-NOT: "-lc" +// CHECK-HWASAN-LINUX: libclang_rt.hwasan-aarch64.a" +// CHECK-HWASAN-LINUX-NOT: "-export-dynamic" +// CHECK-HWASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.hwasan-aarch64.a.syms" +// CHECK-HWASAN-LINUX-NOT: "-export-dynamic" +// CHECK-HWASAN-LINUX: "-lpthread" +// CHECK-HWASAN-LINUX: "-lrt" +// CHECK-HWASAN-LINUX: "-ldl" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \ +// RUN: -shared-libsan \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s +// +// CHECK-SHARED-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-SHARED-HWASAN-LINUX-NOT: "-lc" +// CHECK-SHARED-HWASAN-LINUX: libclang_rt.hwasan-aarch64.so" +// CHECK-SHARED-HWASAN-LINUX-NOT: "-lpthread" +// CHECK-SHARED-HWASAN-LINUX-NOT: "-lrt" +// CHECK-SHARED-HWASAN-LINUX-NOT: "-ldl" +// CHECK-SHARED-HWASAN-LINUX-NOT: "-export-dynamic" +// CHECK-SHARED-HWASAN-LINUX-NOT: "--dynamic-list" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \ +// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-DSO-SHARED-HWASAN-LINUX %s +// +// CHECK-DSO-SHARED-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lc" +// CHECK-DSO-SHARED-HWASAN-LINUX: libclang_rt.hwasan-aarch64.so" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lpthread" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lrt" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-ldl" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-export-dynamic" +// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "--dynamic-list" Index: test/Lexer/has_feature_address_sanitizer.cpp =================================================================== --- test/Lexer/has_feature_address_sanitizer.cpp +++ test/Lexer/has_feature_address_sanitizer.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -E -fsanitize=address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s // RUN: %clang_cc1 -E -fsanitize=kernel-address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s +// RUN: %clang_cc1 -E -fsanitize=hwaddress %s -o - | FileCheck --check-prefix=CHECK-HWASAN %s // RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-ASAN %s #if __has_feature(address_sanitizer) @@ -8,5 +9,17 @@ int AddressSanitizerDisabled(); #endif +#if __has_feature(hwaddress_sanitizer) +int HWAddressSanitizerEnabled(); +#else +int HWAddressSanitizerDisabled(); +#endif + // CHECK-ASAN: AddressSanitizerEnabled +// CHECK-ASAN: HWAddressSanitizerDisabled + +// CHECK-HWASAN: AddressSanitizerDisabled +// CHECK-HWASAN: HWAddressSanitizerEnabled + // CHECK-NO-ASAN: AddressSanitizerDisabled +// CHECK-NO-ASAN: HWAddressSanitizerDisabled Index: test/SemaCXX/attr-no-sanitize.cpp =================================================================== --- test/SemaCXX/attr-no-sanitize.cpp +++ test/SemaCXX/attr-no-sanitize.cpp @@ -16,10 +16,15 @@ // PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]] [[clang::no_sanitize("thread")]] int f4(); +// DUMP-LABEL: FunctionDecl {{.*}} f4 +// DUMP: NoSanitizeAttr {{.*}} hwaddress +// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]] +[[clang::no_sanitize("hwaddress")]] int f4(); + // DUMP-LABEL: FunctionDecl {{.*}} f5 -// DUMP: NoSanitizeAttr {{.*}} address thread -// PRINT: int f5() __attribute__((no_sanitize("address", "thread"))) -int f5() __attribute__((no_sanitize("address", "thread"))); +// DUMP: NoSanitizeAttr {{.*}} address thread hwaddress +// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress"))) +int f5() __attribute__((no_sanitize("address", "thread", "hwaddress"))); // DUMP-LABEL: FunctionDecl {{.*}} f6 // DUMP: NoSanitizeAttr {{.*}} unknown