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