llvm-project/clang/test/CodeGenCXX/lifetime-sanitizer.cpp
Dan Blackwell c63a744f3f
[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
2026-01-22 14:22:44 +00:00

67 lines
2.4 KiB
C++

// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -Xclang -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK \
// RUN: --implicit-check-not=llvm.lifetime
// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -fsanitize=address -fsanitize-address-use-after-scope \
// RUN: -Xclang -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,LIFETIME
// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -fsanitize=kernel-address -fsanitize-address-use-after-scope \
// RUN: -Xclang -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,LIFETIME
// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -fsanitize=memory -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=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);
struct X {
X();
~X();
int *p;
};
struct Y {
Y();
int *p;
};
extern "C" void a(), b(), c(), d();
// CHECK: define dso_local void @_Z3fooi(i32 noundef %[[N:[^)]+]])
void foo(int n) {
// CHECK: store i32 %[[N]], ptr %[[NADDR:[^,]+]]
// CHECK-LABEL: call void @a()
a();
// CHECK-LABEL: call void @b()
// CHECK: [[NARG:%[^ ]+]] = load i32, ptr %[[NADDR]]
// CHECK: [[BOOL:%[^ ]+]] = icmp ne i32 [[NARG]], 0
// CHECK: store i1 false
// CHECK: br i1 [[BOOL]], label %[[ONTRUE:[^,]+]], label %[[ONFALSE:[^,]+]]
//
// CHECK: [[ONTRUE]]:
// LIFETIME: @llvm.lifetime.start
// LIFETIME: store i1 true
// LIFETIME: call void @_ZN1XC
// CHECK: br label %[[END:[^,]+]]
//
// CHECK: [[ONFALSE]]:
// LIFETIME: @llvm.lifetime.start
// LIFETIME: store i1 true
// LIFETIME: call void @_ZN1YC
// CHECK: br label %[[END]]
//
// CHECK: [[END]]:
// CHECK: call void @c()
// LIFETIME: @llvm.lifetime.end
// LIFETIME: @llvm.lifetime.end
b(), (n ? X().p : Y().p), c();
// CHECK: call void @d()
d();
}