diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -42,6 +42,7 @@ FEATURE(hwaddress_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) +FEATURE(memtag_sanitizer, LangOpts.Sanitize.has(SanitizerKind::MemTag)) FEATURE(xray_instrument, LangOpts.XRayInstrument) FEATURE(undefined_behavior_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined)) diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -55,6 +55,9 @@ // Kernel Hardware-assisted AddressSanitizer (KHWASan) SANITIZER("kernel-hwaddress", KernelHWAddress) +// A variant of AddressSanitizer using AArch64 MTE extension. +SANITIZER("memtag", MemTag) + // MemorySanitizer SANITIZER("memory", Memory) diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -355,6 +355,10 @@ !isInSanitizerBlacklist(SanitizerKind::KernelHWAddress, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); + if (getLangOpts().Sanitize.has(SanitizerKind::MemTag) && + !isInSanitizerBlacklist(SanitizerKind::MemTag, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); + if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -696,6 +696,8 @@ Fn->addFnAttr(llvm::Attribute::SanitizeAddress); if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); + if (SanOpts.has(SanitizerKind::MemTag)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2239,9 +2239,11 @@ SourceLocation Loc, QualType Ty, StringRef Category) const { // For now globals can be blacklisted only in ASan and KASan. - const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask & + const SanitizerMask EnabledAsanMask = + LangOpts.Sanitize.Mask & (SanitizerKind::Address | SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress); + SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | + SanitizerKind::MemTag); if (!EnabledAsanMask) return false; const auto &SanitizerBL = getContext().getSanitizerBlacklist(); diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -24,10 +24,10 @@ SourceLocation Loc, StringRef Name, QualType Ty, bool IsDynInit, bool IsBlacklisted) { - if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) + if (!CGM.getLangOpts().Sanitize.hasOneOf( + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | + SanitizerKind::MemTag)) return; IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init"); IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty); @@ -58,10 +58,10 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, bool IsDynInit) { - if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) + if (!CGM.getLangOpts().Sanitize.hasOneOf( + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | + SanitizerKind::MemTag)) return; std::string QualName; llvm::raw_string_ostream OS(QualName); @@ -78,10 +78,10 @@ void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) { // For now, just make sure the global is not modified by the ASan // instrumentation. - if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) + if (CGM.getLangOpts().Sanitize.hasOneOf( + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | + SanitizerKind::MemTag)) reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true); } diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -40,7 +40,8 @@ static const SanitizerMask SupportsCoverage = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | - SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak | + SanitizerKind::MemTag | SanitizerKind::Memory | + SanitizerKind::KernelMemory | SanitizerKind::Leak | SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | SanitizerKind::DataFlow | SanitizerKind::Fuzzer | @@ -121,6 +122,7 @@ SanitizerMask Mask; } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address}, {"hwasan_blacklist.txt", SanitizerKind::HWAddress}, + {"memtag_blacklist.txt", SanitizerKind::MemTag}, {"msan_blacklist.txt", SanitizerKind::Memory}, {"tsan_blacklist.txt", SanitizerKind::Thread}, {"dfsan_abilist.txt", SanitizerKind::DataFlow}, @@ -418,7 +420,11 @@ SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Leak | SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::KernelAddress | - SanitizerKind::Scudo | SanitizerKind::SafeStack)}; + SanitizerKind::Scudo | SanitizerKind::SafeStack), + std::make_pair(SanitizerKind::MemTag, + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -1029,6 +1029,8 @@ Res |= SanitizerKind::HWAddress; Res |= SanitizerKind::KernelHWAddress; } + if (IsAArch64) + Res |= SanitizerKind::MemTag; return Res; } diff --git a/clang/test/CodeGen/memtag-attr.cpp b/clang/test/CodeGen/memtag-attr.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/memtag-attr.cpp @@ -0,0 +1,19 @@ +// Make sure the sanitize_memtag attribute is emitted when using MemTag sanitizer. +// Make sure __attribute__((no_sanitize("memtag")) disables instrumentation. + +// RUN: %clang_cc1 -triple aarch64-unknown-linux -disable-O0-optnone \ +// RUN: -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NO %s + +// RUN: %clang_cc1 -triple aarch64-unknown-linux -fsanitize=memtag \ +// RUN: -disable-O0-optnone -emit-llvm -o - %s | \ +// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s + +int HasSanitizeMemTag() { return 1; } +// CHECK-NO: {{Function Attrs: noinline nounwind$}} +// CHECK-MEMTAG: Function Attrs: noinline nounwind sanitize_memtag + +__attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() { + return 0; +} +// CHECK-NO: {{Function Attrs: noinline nounwind$}} +// CHECK-MEMTAG: {{Function Attrs: noinline nounwind$}} diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -181,6 +181,16 @@ // RUN: %clang -target x86_64-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 aarch64-linux-android -fsanitize=memtag,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-SANA +// CHECK-SANMT-SANA: '-fsanitize=memtag' not allowed with '-fsanitize=address' + +// RUN: %clang -target aarch64-linux-android -fsanitize=memtag,hwaddress -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-SANHA +// CHECK-SANMT-SANHA: '-fsanitize=memtag' not allowed with '-fsanitize=hwaddress' + +// RUN: %clang -target i386-linux-android -fsanitize=memtag -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-BAD-ARCH +// 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 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 diff --git a/clang/test/Lexer/has_feature_memtag_sanitizer.cpp b/clang/test/Lexer/has_feature_memtag_sanitizer.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Lexer/has_feature_memtag_sanitizer.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -E -fsanitize=memtag %s -o - | FileCheck --check-prefix=CHECK-MEMTAG %s +// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-MEMTAG %s + +#if __has_feature(memtag_sanitizer) +int MemTagSanitizerEnabled(); +#else +int MemTagSanitizerDisabled(); +#endif + +// CHECK-MEMTAG: MemTagSanitizerEnabled +// CHECK-NO-MEMTAG: MemTagSanitizerDisabled diff --git a/clang/test/SemaCXX/attr-no-sanitize.cpp b/clang/test/SemaCXX/attr-no-sanitize.cpp --- a/clang/test/SemaCXX/attr-no-sanitize.cpp +++ b/clang/test/SemaCXX/attr-no-sanitize.cpp @@ -30,3 +30,8 @@ // DUMP: NoSanitizeAttr {{.*}} unknown // PRINT: int f6() __attribute__((no_sanitize("unknown"))) int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown sanitizer 'unknown' ignored}} + +// DUMP-LABEL: FunctionDecl {{.*}} f7 +// DUMP: NoSanitizeAttr {{.*}} memtag +// PRINT: int f7() {{\[\[}}clang::no_sanitize("memtag")]] +[[clang::no_sanitize("memtag")]] int f7(); diff --git a/llvm/docs/BitCodeFormat.rst b/llvm/docs/BitCodeFormat.rst --- a/llvm/docs/BitCodeFormat.rst +++ b/llvm/docs/BitCodeFormat.rst @@ -1057,6 +1057,7 @@ * code 56: ``nocf_check`` * code 57: ``optforfuzzing`` * code 58: ``shadowcallstack`` +* code 61: ``sanitize_memtag`` .. note:: The ``allocsize`` attribute has a special encoding for its arguments. Its two diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1660,6 +1660,10 @@ This attribute indicates that HWAddressSanitizer checks (dynamic address safety analysis based on tagged pointers) are enabled for this function. +``sanitize_memtag`` + This attribute indicates that MemTagSanitizer checks + (dynamic address safety analysis based on Armv8 MTE) are enabled for + this function. ``speculative_load_hardening`` This attribute indicates that `Speculative Load Hardening `_ diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -629,6 +629,7 @@ ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59, ATTR_KIND_IMMARG = 60, ATTR_KIND_WILLRETURN = 61, + ATTR_KIND_SANITIZE_MEMTAG = 62 }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -179,6 +179,9 @@ /// HWAddressSanitizer is on. def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">; +/// MemTagSanitizer is on. +def SanitizeMemTag : EnumAttr<"sanitize_memtag">; + /// Speculative Load Hardening is enabled. /// /// Note that this uses the default compatibility (always compatible during @@ -227,6 +230,7 @@ def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; +def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -677,6 +677,7 @@ KEYWORD(shadowcallstack); KEYWORD(sanitize_address); KEYWORD(sanitize_hwaddress); + KEYWORD(sanitize_memtag); KEYWORD(sanitize_thread); KEYWORD(sanitize_memory); KEYWORD(speculative_load_hardening); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1309,6 +1309,8 @@ B.addAttribute(Attribute::SanitizeAddress); break; case lltok::kw_sanitize_hwaddress: B.addAttribute(Attribute::SanitizeHWAddress); break; + case lltok::kw_sanitize_memtag: + B.addAttribute(Attribute::SanitizeMemTag); break; case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; case lltok::kw_sanitize_memory: @@ -1666,6 +1668,7 @@ case lltok::kw_returns_twice: case lltok::kw_sanitize_address: case lltok::kw_sanitize_hwaddress: + case lltok::kw_sanitize_memtag: case lltok::kw_sanitize_memory: case lltok::kw_sanitize_thread: case lltok::kw_speculative_load_hardening: @@ -1764,6 +1767,7 @@ case lltok::kw_returns_twice: case lltok::kw_sanitize_address: case lltok::kw_sanitize_hwaddress: + case lltok::kw_sanitize_memtag: case lltok::kw_sanitize_memory: case lltok::kw_sanitize_thread: case lltok::kw_speculative_load_hardening: diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -175,6 +175,7 @@ kw_argmemonly, kw_sanitize_address, kw_sanitize_hwaddress, + kw_sanitize_memtag, kw_builtin, kw_byval, kw_inalloca, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1278,6 +1278,8 @@ return 1ULL << 61; case Attribute::WillReturn: return 1ULL << 62; + case Attribute::SanitizeMemTag: + return 1ULL << 63; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1524,6 +1526,8 @@ return Attribute::ZExt; case bitc::ATTR_KIND_IMMARG: return Attribute::ImmArg; + case bitc::ATTR_KIND_SANITIZE_MEMTAG: + return Attribute::SanitizeMemTag; } } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -719,6 +719,8 @@ return bitc::ATTR_KIND_Z_EXT; case Attribute::ImmArg: return bitc::ATTR_KIND_IMMARG; + case Attribute::SanitizeMemTag: + return bitc::ATTR_KIND_SANITIZE_MEMTAG; case Attribute::EndAttrKinds: llvm_unreachable("Can not encode end-attribute kinds marker."); case Attribute::None: diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -283,6 +283,8 @@ return "sanitize_address"; if (hasAttribute(Attribute::SanitizeHWAddress)) return "sanitize_hwaddress"; + if (hasAttribute(Attribute::SanitizeMemTag)) + return "sanitize_memtag"; if (hasAttribute(Attribute::AlwaysInline)) return "alwaysinline"; if (hasAttribute(Attribute::ArgMemOnly)) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1507,6 +1507,7 @@ case Attribute::ReturnsTwice: case Attribute::SanitizeAddress: case Attribute::SanitizeHWAddress: + case Attribute::SanitizeMemTag: case Attribute::SanitizeThread: case Attribute::SanitizeMemory: case Attribute::MinSize: diff --git a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp --- a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp @@ -57,6 +57,7 @@ .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress) .Case("sanitize_memory", Attribute::SanitizeMemory) .Case("sanitize_thread", Attribute::SanitizeThread) + .Case("sanitize_memtag", Attribute::SanitizeMemTag) .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening) .Case("ssp", Attribute::StackProtect) .Case("sspreq", Attribute::StackProtectReq) diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -828,6 +828,7 @@ case Attribute::SanitizeMemory: case Attribute::SanitizeThread: case Attribute::SanitizeHWAddress: + case Attribute::SanitizeMemTag: case Attribute::SpeculativeLoadHardening: case Attribute::StackProtect: case Attribute::StackProtectReq: diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -204,7 +204,7 @@ ; CHECK: define void @f34() { call void @nobuiltin() nobuiltin -; CHECK: call void @nobuiltin() #37 +; CHECK: call void @nobuiltin() #38 ret void; } @@ -357,6 +357,12 @@ ret void } +; CHECK: define void @f61() #37 +define void @f61() sanitize_memtag +{ + ret void; +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -394,4 +400,5 @@ ; CHECK: attributes #34 = { sanitize_hwaddress } ; CHECK: attributes #35 = { shadowcallstack } ; CHECK: attributes #36 = { willreturn } -; CHECK: attributes #37 = { nobuiltin } +; CHECK: attributes #37 = { sanitize_memtag } +; CHECK: attributes #38 = { nobuiltin } diff --git a/llvm/test/Transforms/Inline/attributes.ll b/llvm/test/Transforms/Inline/attributes.ll --- a/llvm/test/Transforms/Inline/attributes.ll +++ b/llvm/test/Transforms/Inline/attributes.ll @@ -22,6 +22,10 @@ ret i32 %i } +define i32 @sanitize_memtag_callee(i32 %i) sanitize_memtag { + ret i32 %i +} + define i32 @safestack_callee(i32 %i) safestack { ret i32 %i } @@ -50,6 +54,10 @@ ret i32 %i } +define i32 @alwaysinline_sanitize_memtag_callee(i32 %i) alwaysinline sanitize_memtag { + ret i32 %i +} + define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack { ret i32 %i } @@ -104,6 +112,17 @@ ; CHECK-NEXT: ret i32 } +define i32 @test_no_sanitize_memtag(i32 %arg) { + %x1 = call i32 @noattr_callee(i32 %arg) + %x2 = call i32 @sanitize_memtag_callee(i32 %x1) + %x3 = call i32 @alwaysinline_callee(i32 %x2) + %x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3) + ret i32 %x4 +; CHECK-LABEL: @test_no_sanitize_memtag( +; CHECK-NEXT: @sanitize_memtag_callee +; CHECK-NEXT: ret i32 +} + ; Check that: ; * noattr callee is not inlined into sanitize_(address|memory|thread) caller, @@ -154,6 +173,17 @@ ; CHECK-NEXT: ret i32 } +define i32 @test_sanitize_memtag(i32 %arg) sanitize_memtag { + %x1 = call i32 @noattr_callee(i32 %arg) + %x2 = call i32 @sanitize_memtag_callee(i32 %x1) + %x3 = call i32 @alwaysinline_callee(i32 %x2) + %x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3) + ret i32 %x4 +; CHECK-LABEL: @test_sanitize_memtag( +; CHECK-NEXT: @noattr_callee +; CHECK-NEXT: ret i32 +} + define i32 @test_safestack(i32 %arg) safestack { %x1 = call i32 @noattr_callee(i32 %arg) %x2 = call i32 @safestack_callee(i32 %x1) diff --git a/llvm/utils/emacs/llvm-mode.el b/llvm/utils/emacs/llvm-mode.el --- a/llvm/utils/emacs/llvm-mode.el +++ b/llvm/utils/emacs/llvm-mode.el @@ -26,7 +26,7 @@ "inaccessiblemem_or_argmemonly" "inlinehint" "jumptable" "minsize" "naked" "nobuiltin" "noduplicate" "noimplicitfloat" "noinline" "nonlazybind" "noredzone" "noreturn" "norecurse" "nounwind" "optnone" "optsize" "readnone" "readonly" "returns_twice" - "speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" + "speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag" "sanitize_thread" "sanitize_memory" "strictfp" "uwtable" "writeonly" "immarg") 'symbols) . font-lock-constant-face) ;; Variables '("%[-a-zA-Z$._][-a-zA-Z$._0-9]*" . font-lock-variable-name-face)