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