xref: /aosp_15_r20/external/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // See Test9 for test description.
4*67e74705SXin Li // CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant
5*67e74705SXin Li namespace Test1 {
6*67e74705SXin Li 
7*67e74705SXin Li // Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.
8*67e74705SXin Li struct A {
9*67e74705SXin Li   virtual void f();
10*67e74705SXin Li   ~A();
11*67e74705SXin Li };
12*67e74705SXin Li 
13*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test11AD2Ev
14*67e74705SXin Li // CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()15*67e74705SXin Li A::~A()
16*67e74705SXin Li {
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li }
20*67e74705SXin Li 
21*67e74705SXin Li namespace Test2 {
22*67e74705SXin Li 
23*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.
24*67e74705SXin Li struct A {
25*67e74705SXin Li   virtual void f();
26*67e74705SXin Li   ~A();
27*67e74705SXin Li };
28*67e74705SXin Li 
29*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test21AD2Ev
30*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()31*67e74705SXin Li A::~A() {
32*67e74705SXin Li   f();
33*67e74705SXin Li }
34*67e74705SXin Li 
35*67e74705SXin Li }
36*67e74705SXin Li 
37*67e74705SXin Li namespace Test3 {
38*67e74705SXin Li 
39*67e74705SXin Li // Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial
40*67e74705SXin Li // and Field's destructor body is also trivial.
41*67e74705SXin Li struct Field {
~FieldTest3::Field42*67e74705SXin Li   ~Field() { }
43*67e74705SXin Li };
44*67e74705SXin Li 
45*67e74705SXin Li struct A {
46*67e74705SXin Li   virtual void f();
47*67e74705SXin Li   ~A();
48*67e74705SXin Li 
49*67e74705SXin Li   Field field;
50*67e74705SXin Li };
51*67e74705SXin Li 
52*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test31AD2Ev
53*67e74705SXin Li // CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test31AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()54*67e74705SXin Li A::~A() {
55*67e74705SXin Li 
56*67e74705SXin Li }
57*67e74705SXin Li 
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li namespace Test4 {
61*67e74705SXin Li 
62*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body
63*67e74705SXin Li // isn't trivial.
64*67e74705SXin Li 
65*67e74705SXin Li void f();
66*67e74705SXin Li 
67*67e74705SXin Li struct Field {
~FieldTest4::Field68*67e74705SXin Li   ~Field() { f(); }
69*67e74705SXin Li };
70*67e74705SXin Li 
71*67e74705SXin Li struct A {
72*67e74705SXin Li   virtual void f();
73*67e74705SXin Li   ~A();
74*67e74705SXin Li 
75*67e74705SXin Li   Field field;
76*67e74705SXin Li };
77*67e74705SXin Li 
78*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test41AD2Ev
79*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test41AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()80*67e74705SXin Li A::~A()
81*67e74705SXin Li {
82*67e74705SXin Li }
83*67e74705SXin Li 
84*67e74705SXin Li }
85*67e74705SXin Li 
86*67e74705SXin Li namespace Test5 {
87*67e74705SXin Li 
88*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't
89*67e74705SXin Li // available in this translation unit.
90*67e74705SXin Li 
91*67e74705SXin Li struct Field {
92*67e74705SXin Li   ~Field();
93*67e74705SXin Li };
94*67e74705SXin Li 
95*67e74705SXin Li struct A {
96*67e74705SXin Li   virtual void f();
97*67e74705SXin Li   ~A();
98*67e74705SXin Li 
99*67e74705SXin Li   Field field;
100*67e74705SXin Li };
101*67e74705SXin Li 
102*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test51AD2Ev
103*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test51AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()104*67e74705SXin Li A::~A()
105*67e74705SXin Li {
106*67e74705SXin Li }
107*67e74705SXin Li 
108*67e74705SXin Li }
109*67e74705SXin Li 
110*67e74705SXin Li namespace Test6 {
111*67e74705SXin Li 
112*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A(), since Field has a member
113*67e74705SXin Li // variable with a non-trivial destructor body.
114*67e74705SXin Li 
115*67e74705SXin Li struct NonTrivialDestructorBody {
116*67e74705SXin Li   ~NonTrivialDestructorBody();
117*67e74705SXin Li };
118*67e74705SXin Li 
119*67e74705SXin Li struct Field {
120*67e74705SXin Li   NonTrivialDestructorBody nonTrivialDestructorBody;
121*67e74705SXin Li };
122*67e74705SXin Li 
123*67e74705SXin Li struct A {
124*67e74705SXin Li   virtual void f();
125*67e74705SXin Li   ~A();
126*67e74705SXin Li 
127*67e74705SXin Li   Field field;
128*67e74705SXin Li };
129*67e74705SXin Li 
130*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test61AD2Ev
131*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test61AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()132*67e74705SXin Li A::~A()
133*67e74705SXin Li {
134*67e74705SXin Li }
135*67e74705SXin Li 
136*67e74705SXin Li }
137*67e74705SXin Li 
138*67e74705SXin Li namespace Test7 {
139*67e74705SXin Li 
140*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A(), since Field has a base
141*67e74705SXin Li // class with a non-trivial destructor body.
142*67e74705SXin Li 
143*67e74705SXin Li struct NonTrivialDestructorBody {
144*67e74705SXin Li   ~NonTrivialDestructorBody();
145*67e74705SXin Li };
146*67e74705SXin Li 
147*67e74705SXin Li struct Field : NonTrivialDestructorBody { };
148*67e74705SXin Li 
149*67e74705SXin Li struct A {
150*67e74705SXin Li   virtual void f();
151*67e74705SXin Li   ~A();
152*67e74705SXin Li 
153*67e74705SXin Li   Field field;
154*67e74705SXin Li };
155*67e74705SXin Li 
156*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test71AD2Ev
157*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test71AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()158*67e74705SXin Li A::~A()
159*67e74705SXin Li {
160*67e74705SXin Li }
161*67e74705SXin Li 
162*67e74705SXin Li }
163*67e74705SXin Li 
164*67e74705SXin Li namespace Test8 {
165*67e74705SXin Li 
166*67e74705SXin Li // Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
167*67e74705SXin Li // class with a non-trivial destructor body.
168*67e74705SXin Li 
169*67e74705SXin Li struct NonTrivialDestructorBody {
170*67e74705SXin Li   ~NonTrivialDestructorBody();
171*67e74705SXin Li };
172*67e74705SXin Li 
173*67e74705SXin Li struct Field : virtual NonTrivialDestructorBody { };
174*67e74705SXin Li 
175*67e74705SXin Li struct A {
176*67e74705SXin Li   virtual void f();
177*67e74705SXin Li   ~A();
178*67e74705SXin Li 
179*67e74705SXin Li   Field field;
180*67e74705SXin Li };
181*67e74705SXin Li 
182*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test81AD2Ev
183*67e74705SXin Li // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test81AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
~A()184*67e74705SXin Li A::~A()
185*67e74705SXin Li {
186*67e74705SXin Li }
187*67e74705SXin Li 
188*67e74705SXin Li }
189*67e74705SXin Li 
190*67e74705SXin Li namespace Test9 {
191*67e74705SXin Li 
192*67e74705SXin Li // Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.
~ATest9::A193*67e74705SXin Li struct A { virtual ~A () { } };
194*67e74705SXin Li struct B : virtual A {};
195*67e74705SXin Li struct C : virtual B {
196*67e74705SXin Li   virtual ~C();
197*67e74705SXin Li };
~C()198*67e74705SXin Li C::~C() {}
199*67e74705SXin Li 
200*67e74705SXin Li }
201