1 // Test -fsanitize-memory-use-after-dtor 2 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s 3 4 struct Simple { 5 ~Simple() {} 6 }; 7 Simple s; 8 // Simple internal member is poisoned by compiler-generated dtor 9 // CHECK-LABEL: define {{.*}}SimpleD1Ev 10 // CHECK: call void @__sanitizer_dtor_callback 11 // CHECK-NOT: call void @__sanitizer_dtor_callback 12 // CHECK: ret void 13 14 struct Inlined { 15 inline ~Inlined() {} 16 }; 17 Inlined i; 18 // Simple internal member is poisoned by compiler-generated dtor 19 // CHECK-LABEL: define {{.*}}InlinedD1Ev 20 // CHECK: call void @__sanitizer_dtor_callback 21 // CHECK-NOT: call void @__sanitizer_dtor_callback 22 // CHECK: ret void 23 24 struct Defaulted_Trivial { 25 ~Defaulted_Trivial() = default; 26 }; 27 void create_def_trivial() { 28 Defaulted_Trivial def_trivial; 29 } 30 // The compiler is explicitly signalled to handle object cleanup. 31 // No complex member attributes. Compiler destroys inline, so 32 // no destructor defined. 33 // CHECK-LABEL: define {{.*}}create_def_trivial 34 // CHECK-NOT: call {{.*}}Defaulted_Trivial 35 // CHECK-NOT: call void @__sanitizer_dtor_callback 36 // CHECK: ret void 37 38 struct Defaulted_Non_Trivial { 39 Simple s; 40 ~Defaulted_Non_Trivial() = default; 41 }; 42 Defaulted_Non_Trivial def_non_trivial; 43 // Explicitly compiler-generated dtor poisons object. 44 // By including a Simple member in the struct, the compiler is 45 // forced to generate a non-trivial destructor. 46 // CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD1Ev 47 // CHECK: call void @__sanitizer_dtor_callback 48 // CHECK-NOT: call void @__sanitizer_dtor_callback 49 // CHECK: ret void 50 51 52 // Note: ordering is important. In the emitted bytecode, these 53 // second dtors defined after the first. Explicitly checked here 54 // to confirm that all invoked dtors have member poisoning 55 // instrumentation inserted. 56 // CHECK-LABEL: define {{.*}}SimpleD2Ev 57 // CHECK: call void @__sanitizer_dtor_callback 58 // CHECK-NOT: call void @__sanitizer_dtor_callback 59 // CHECK: ret void 60 61 // CHECK-LABEL: define {{.*}}InlinedD2Ev 62 // CHECK: call void @__sanitizer_dtor_callback 63 // CHECK-NOT: call void @__sanitizer_dtor_callback 64 // CHECK: ret void 65 66 // CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD2Ev 67 // CHECK: call void @__sanitizer_dtor_callback 68 // CHECK-NOT: call void @__sanitizer_dtor_callback 69 // CHECK: ret void 70