Author: Dan Blackwell Date: 2026-01-22T14:22:44Z New Revision: c63a744f3fbc91f0f544d79a50ae91e860d092b7
URL: https://github.com/llvm/llvm-project/commit/c63a744f3fbc91f0f544d79a50ae91e860d092b7 DIFF: https://github.com/llvm/llvm-project/commit/c63a744f3fbc91f0f544d79a50ae91e860d092b7.diff LOG: [CodeGen][InstCombine][Sanitizers] Emit lifetimes when compiling with memtag-stack (#177130) Currently we do not emit lifetimes by default when compiling with memtag-stack - which means we don't catch use-after-scope (when compiling without optimization). This patch fixes that by mirroring ASan, HWASan and MSan, and always emitting lifetime markers. The patch is based on the changes made in aeca569. rdar://163713381 Added: Modified: clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CodeGen/lifetime-sanitizer.c clang/test/CodeGenCXX/lifetime-sanitizer.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 2a5ae8da72512..76a3939cd28eb 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -620,6 +620,7 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { if (isInConditionalBranch() && !E->getType().isDestructedType() && ((!SanOpts.has(SanitizerKind::HWAddress) && !SanOpts.has(SanitizerKind::Memory) && + !SanOpts.has(SanitizerKind::MemtagStack) && !CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) || inSuspendBlock())) { OldConditional = OutermostConditional; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index bec359eb2b6b3..1ddcfbbe6461b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -69,7 +69,8 @@ static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, // Sanitizers may use markers. if (CGOpts.SanitizeAddressUseAfterScope || LangOpts.Sanitize.has(SanitizerKind::HWAddress) || - LangOpts.Sanitize.has(SanitizerKind::Memory)) + LangOpts.Sanitize.has(SanitizerKind::Memory) || + LangOpts.Sanitize.has(SanitizerKind::MemtagStack)) return true; // For now, only in optimized builds. diff --git a/clang/test/CodeGen/lifetime-sanitizer.c b/clang/test/CodeGen/lifetime-sanitizer.c index 4d36bd7a9fee5..e529dccc35cc4 100644 --- a/clang/test/CodeGen/lifetime-sanitizer.c +++ b/clang/test/CodeGen/lifetime-sanitizer.c @@ -12,6 +12,9 @@ // RUN: %clang -target aarch64-linux-gnu -S -emit-llvm -o - -O0 \ // RUN: -fsanitize=hwaddress -Xclang -disable-llvm-passes %s | \ // RUN: FileCheck %s -check-prefix=LIFETIME +// RUN: %clang -target aarch64-linux-gnu -S -emit-llvm -o - -O0 \ +// RUN: -fsanitize=memtag-stack -march=armv8a+memtag -Xclang -disable-llvm-passes %s | \ +// RUN: FileCheck %s -check-prefix=LIFETIME extern int bar(char *A, int n); diff --git a/clang/test/CodeGenCXX/lifetime-sanitizer.cpp b/clang/test/CodeGenCXX/lifetime-sanitizer.cpp index 225d5e28921b8..a1557b03082b6 100644 --- a/clang/test/CodeGenCXX/lifetime-sanitizer.cpp +++ b/clang/test/CodeGenCXX/lifetime-sanitizer.cpp @@ -13,6 +13,9 @@ // RUN: %clang -w -target aarch64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \ // RUN: -fsanitize=hwaddress -Xclang -disable-llvm-passes %s | \ // RUN: FileCheck %s -check-prefixes=CHECK,LIFETIME +// RUN: %clang -w -target aarch64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \ +// RUN: -fsanitize=memtag-stack -march=armv8a+memtag -Xclang -disable-llvm-passes %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,LIFETIME extern int bar(char *A, int n); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index b870ac259d3b0..00b45545178ae 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3524,7 +3524,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { // even for empty lifetime range. if (II->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) || II->getFunction()->hasFnAttribute(Attribute::SanitizeMemory) || - II->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress)) + II->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress) || + II->getFunction()->hasFnAttribute(Attribute::SanitizeMemTag)) break; if (removeTriviallyEmptyRange(*II, *this, [](const IntrinsicInst &I) { diff --git a/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll b/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll index fd45fe2dd27d7..2f4e3e3528a2e 100644 --- a/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll +++ b/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll @@ -34,6 +34,21 @@ entry: ret void } +define void @memtag() sanitize_memtag { +entry: + ; CHECK-LABEL: @memtag( + %text = alloca i8, align 1 + + call void @llvm.lifetime.start.p0(ptr %text) + call void @llvm.lifetime.end.p0(ptr %text) + ; CHECK: call void @llvm.lifetime.start + ; CHECK-NEXT: call void @llvm.lifetime.end + + call void @foo(ptr %text) ; Keep alloca alive + + ret void +} + define void @msan() sanitize_memory { entry: ; CHECK-LABEL: @msan( _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
