mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-25 06:18:56 -04:00

When a non-extended temporary object is created in a conditional branch, the lifetime of that temporary ends outside the conditional (at the end of the full-expression). If we're inserting lifetime markers, this means we could end up generating if (some_cond) { lifetime.start(&tmp); Tmp::Tmp(&tmp); } // ... if (some_cond) { lifetime.end(&tmp); } ... for a full-expression containing a subexpression of the form `some_cond ? Tmp().x : 0`. This patch moves the lifetime start for such a temporary out of the conditional branch so that we don't need to generate an additional basic block to hold the lifetime end marker. This is disabled if we want precise lifetime markers (for asan's stack-use-after-scope checks) or of the temporary has a non-trivial destructor (in which case we'd generate an extra basic block anyway to hold the destructor call). Differential Revision: https://reviews.llvm.org/D50286 llvm-svn: 338945
43 lines
1.3 KiB
C++
43 lines
1.3 KiB
C++
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 %s | FileCheck %s -check-prefixes=CHECK,CHECK-O0 --implicit-check-not=llvm.lifetime
|
|
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
|
|
// RUN: -fsanitize=address -fsanitize-address-use-after-scope %s | \
|
|
// RUN: FileCheck %s -check-prefixes=CHECK,CHECK-ASAN-USE-AFTER-SCOPE
|
|
|
|
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-LABEL: @_Z3foo
|
|
void foo(int n) {
|
|
// CHECK: call void @a()
|
|
a();
|
|
|
|
// CHECK: call void @b()
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
|
|
// CHECK: br i1
|
|
//
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
|
|
// CHECK: call void @_ZN1XC
|
|
// CHECK: br label
|
|
//
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
|
|
// CHECK: call void @_ZN1YC
|
|
// CHECK: br label
|
|
//
|
|
// CHECK: call void @c()
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: br i1
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: br i1
|
|
// CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
|
|
b(), (n ? X().p : Y().p), c();
|
|
|
|
// CHECK: call void @d()
|
|
d();
|
|
}
|