263 lines · cpp
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s2 3// See Test9 for test description.4// CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant5namespace Test1 {6 7// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.8struct A {9 virtual void f();10 ~A();11};12 13// CHECK-LABEL: define{{.*}} void @_ZN5Test11AD2Ev14// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test11AE, i64 0, i64 2), ptr15A::~A() 16{17}18 19}20 21namespace Test2 {22 23// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.24struct A {25 virtual void f();26 ~A();27};28 29// CHECK-LABEL: define{{.*}} void @_ZN5Test21AD2Ev30// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test21AE, i32 0, i32 0, i32 2), ptr31A::~A() {32 f();33}34 35}36 37namespace Test3 {38 39// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial40// and Field's destructor body is also trivial.41struct Field {42 ~Field() { }43};44 45struct A {46 virtual void f();47 ~A();48 49 Field field;50};51 52// CHECK-LABEL: define{{.*}} void @_ZN5Test31AD2Ev53// CHECK-NOT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test31AE, i32 0, i32 0, i32 2), ptr54A::~A() {55 56}57 58}59 60namespace Test4 {61 62// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body63// isn't trivial.64 65void f();66 67struct Field {68 ~Field() { f(); }69};70 71struct A {72 virtual void f();73 ~A();74 75 Field field;76};77 78// CHECK-LABEL: define{{.*}} void @_ZN5Test41AD2Ev79// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test41AE, i32 0, i32 0, i32 2), ptr80A::~A()81{82}83 84}85 86namespace Test5 {87 88// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't89// available in this translation unit.90 91struct Field {92 ~Field();93};94 95struct A {96 virtual void f();97 ~A();98 99 Field field;100};101 102// CHECK-LABEL: define{{.*}} void @_ZN5Test51AD2Ev103// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test51AE, i32 0, i32 0, i32 2), ptr104A::~A()105{106}107 108}109 110namespace Test6 {111 112// Check that we do initialize the vtable pointer in A::~A(), since Field has a member113// variable with a non-trivial destructor body.114 115struct NonTrivialDestructorBody {116 ~NonTrivialDestructorBody();117};118 119struct Field {120 NonTrivialDestructorBody nonTrivialDestructorBody;121};122 123struct A {124 virtual void f();125 ~A();126 127 Field field;128};129 130// CHECK-LABEL: define{{.*}} void @_ZN5Test61AD2Ev131// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test61AE, i32 0, i32 0, i32 2), ptr132A::~A()133{134}135 136}137 138namespace Test7 {139 140// Check that we do initialize the vtable pointer in A::~A(), since Field has a base141// class with a non-trivial destructor body.142 143struct NonTrivialDestructorBody {144 ~NonTrivialDestructorBody();145};146 147struct Field : NonTrivialDestructorBody { };148 149struct A {150 virtual void f();151 ~A();152 153 Field field;154};155 156// CHECK-LABEL: define{{.*}} void @_ZN5Test71AD2Ev157// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test71AE, i32 0, i32 0, i32 2), ptr158A::~A()159{160}161 162}163 164namespace Test8 {165 166// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base167// class with a non-trivial destructor body.168 169struct NonTrivialDestructorBody {170 ~NonTrivialDestructorBody();171};172 173struct Field : virtual NonTrivialDestructorBody { };174 175struct A {176 virtual void f();177 ~A();178 179 Field field;180};181 182// CHECK-LABEL: define{{.*}} void @_ZN5Test81AD2Ev183// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test81AE, i32 0, i32 0, i32 2), ptr184A::~A()185{186}187 188}189 190namespace Test9 {191 192// Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.193struct A { virtual ~A () { } };194struct B : virtual A {};195struct C : virtual B { 196 virtual ~C();197};198C::~C() {}199 200}201 202namespace Test10 {203 204// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous union which205// never has its destructor invoked.206struct A {207 virtual void f();208 ~A();209 210 union211 {212 int i;213 unsigned u;214 };215};216 217// CHECK-LABEL: define{{.*}} void @_ZN6Test101AD2Ev218// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test101AE, i32 0, inrange i32 0, i32 2), ptr219A::~A() {220}221 222}223 224namespace Test11 {225 226// Check that we don't initialize the vtable pointer in A::~A(), even if the base class has a non trivial destructor.227struct Field {228 ~Field();229};230 231struct A : public Field {232 virtual void f();233 ~A();234};235 236// CHECK-LABEL: define{{.*}} void @_ZN6Test111AD2Ev237// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test111AE, i32 0, inrange i32 0, i32 2), ptr238A::~A() {239}240 241}242 243namespace Test12 {244 245// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous struct with trivial fields.246struct A {247 virtual void f();248 ~A();249 250 struct251 {252 int i;253 unsigned u;254 };255};256 257// CHECK-LABEL: define{{.*}} void @_ZN6Test121AD2Ev258// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test121AE, i32 0, inrange i32 0, i32 2), ptr259A::~A() {260}261 262}263