xref: /aosp_15_r20/external/clang/test/CodeGenCXX/value-init.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 struct A {
4*67e74705SXin Li   virtual ~A();
5*67e74705SXin Li };
6*67e74705SXin Li 
7*67e74705SXin Li struct B : A { };
8*67e74705SXin Li 
9*67e74705SXin Li struct C {
10*67e74705SXin Li   int i;
11*67e74705SXin Li   B b;
12*67e74705SXin Li };
13*67e74705SXin Li 
14*67e74705SXin Li // CHECK: _Z15test_value_initv
test_value_init()15*67e74705SXin Li void test_value_init() {
16*67e74705SXin Li   // This value initialization requires zero initialization of the 'B'
17*67e74705SXin Li   // subobject followed by a call to its constructor.
18*67e74705SXin Li   // PR5800
19*67e74705SXin Li 
20*67e74705SXin Li   // CHECK: store i32 17
21*67e74705SXin Li   // CHECK: call void @llvm.memset.p0i8.i64
22*67e74705SXin Li   // CHECK: call void @_ZN1BC1Ev
23*67e74705SXin Li   C c = { 17 } ;
24*67e74705SXin Li   // CHECK: call void @_ZN1CD1Ev
25*67e74705SXin Li }
26*67e74705SXin Li 
27*67e74705SXin Li enum enum_type { negative_number = -1, magic_number = 42 };
28*67e74705SXin Li 
29*67e74705SXin Li class enum_holder
30*67e74705SXin Li {
31*67e74705SXin Li   enum_type m_enum;
32*67e74705SXin Li 
33*67e74705SXin Li public:
enum_holder()34*67e74705SXin Li   enum_holder() : m_enum(magic_number) { }
35*67e74705SXin Li };
36*67e74705SXin Li 
37*67e74705SXin Li struct enum_holder_and_int
38*67e74705SXin Li {
39*67e74705SXin Li   enum_holder e;
40*67e74705SXin Li   int i;
41*67e74705SXin Li };
42*67e74705SXin Li 
43*67e74705SXin Li // CHECK: _Z24test_enum_holder_and_intv()
test_enum_holder_and_int()44*67e74705SXin Li void test_enum_holder_and_int() {
45*67e74705SXin Li   // CHECK: alloca
46*67e74705SXin Li   // CHECK-NEXT: bitcast
47*67e74705SXin Li   // CHECK-NEXT: call void @llvm.memset
48*67e74705SXin Li   // CHECK-NEXT: call void @_ZN19enum_holder_and_intC1Ev
49*67e74705SXin Li   enum_holder_and_int();
50*67e74705SXin Li   // CHECK-NEXT: ret void
51*67e74705SXin Li }
52*67e74705SXin Li 
53*67e74705SXin Li // PR7834: don't crash.
54*67e74705SXin Li namespace test1 {
55*67e74705SXin Li   struct A {
56*67e74705SXin Li     int A::*f;
57*67e74705SXin Li     A();
58*67e74705SXin Li     A(const A&);
59*67e74705SXin Li     A &operator=(const A &);
60*67e74705SXin Li   };
61*67e74705SXin Li 
62*67e74705SXin Li   struct B {
63*67e74705SXin Li     A base;
64*67e74705SXin Li   };
65*67e74705SXin Li 
foo()66*67e74705SXin Li   void foo() {
67*67e74705SXin Li     B();
68*67e74705SXin Li   }
69*67e74705SXin Li }
70*67e74705SXin Li 
71*67e74705SXin Li namespace ptrmem {
72*67e74705SXin Li   struct S {
73*67e74705SXin Li     int mem1;
74*67e74705SXin Li     int S::*mem2;
75*67e74705SXin Li   };
76*67e74705SXin Li 
77*67e74705SXin Li   // CHECK-LABEL: define i32 @_ZN6ptrmem4testEPNS_1SE
test(S * s)78*67e74705SXin Li   int test(S *s) {
79*67e74705SXin Li     // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
80*67e74705SXin Li     // CHECK: getelementptr
81*67e74705SXin Li     // CHECK: ret
82*67e74705SXin Li     return s->*S().mem2;
83*67e74705SXin Li   }
84*67e74705SXin Li }
85*67e74705SXin Li 
86*67e74705SXin Li namespace PR9801 {
87*67e74705SXin Li 
88*67e74705SXin Li struct Test {
TestPR9801::Test89*67e74705SXin Li   Test() : i(10) {}
TestPR9801::Test90*67e74705SXin Li   Test(int i) : i(i) {}
91*67e74705SXin Li   int i;
92*67e74705SXin Li private:
93*67e74705SXin Li   int j;
94*67e74705SXin Li };
95*67e74705SXin Li 
96*67e74705SXin Li struct Test2 {
97*67e74705SXin Li   Test t;
98*67e74705SXin Li };
99*67e74705SXin Li 
100*67e74705SXin Li struct Test3 : public Test { };
101*67e74705SXin Li 
102*67e74705SXin Li // CHECK-LABEL: define void @_ZN6PR98011fEv
f()103*67e74705SXin Li void f() {
104*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
105*67e74705SXin Li   // CHECK: call void @_ZN6PR98014TestC1Ei
106*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
107*67e74705SXin Li   // CHECK: call void @_ZN6PR98014TestC1Ev
108*67e74705SXin Li   Test partial[3] = { 1 };
109*67e74705SXin Li 
110*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
111*67e74705SXin Li   // CHECK: call void @_ZN6PR98014TestC1Ev
112*67e74705SXin Li   // CHECK-NOT: call void @_ZN6PR98014TestC1Ev
113*67e74705SXin Li   Test empty[3] = {};
114*67e74705SXin Li 
115*67e74705SXin Li   // CHECK: call void @llvm.memset.p0i8.i64
116*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
117*67e74705SXin Li   // CHECK: call void @_ZN6PR98015Test2C1Ev
118*67e74705SXin Li   // CHECK-NOT: call void @_ZN6PR98015Test2C1Ev
119*67e74705SXin Li   Test2 empty2[3] = {};
120*67e74705SXin Li 
121*67e74705SXin Li   // CHECK: call void @llvm.memset.p0i8.i64
122*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
123*67e74705SXin Li   // CHECK: call void @_ZN6PR98015Test3C1Ev
124*67e74705SXin Li   // CHECK-NOT: call void @llvm.memset.p0i8.i64
125*67e74705SXin Li   // CHECK-NOT: call void @_ZN6PR98015Test3C1Ev
126*67e74705SXin Li   Test3 empty3[3] = {};
127*67e74705SXin Li }
128*67e74705SXin Li 
129*67e74705SXin Li }
130*67e74705SXin Li 
131*67e74705SXin Li namespace zeroinit {
132*67e74705SXin Li   struct S { int i; };
133*67e74705SXin Li 
134*67e74705SXin Li   // CHECK-LABEL: define i32 @_ZN8zeroinit4testEv()
test()135*67e74705SXin Li   int test() {
136*67e74705SXin Li     // CHECK: call void @llvm.memset.p0i8.i64
137*67e74705SXin Li     // CHECK: ret i32 0
138*67e74705SXin Li     return S().i;
139*67e74705SXin Li   }
140*67e74705SXin Li 
141*67e74705SXin Li   struct X0 {
X0zeroinit::X0142*67e74705SXin Li     X0() { }
143*67e74705SXin Li     int x;
144*67e74705SXin Li   };
145*67e74705SXin Li 
146*67e74705SXin Li   struct X1 : X0 {
147*67e74705SXin Li     int x1;
148*67e74705SXin Li     void f();
149*67e74705SXin Li   };
150*67e74705SXin Li 
151*67e74705SXin Li   // CHECK-LABEL: define void @_ZN8zeroinit9testX0_X1Ev
testX0_X1()152*67e74705SXin Li   void testX0_X1() {
153*67e74705SXin Li     // CHECK: call void @llvm.memset.p0i8.i64
154*67e74705SXin Li     // CHECK-NEXT: call void @_ZN8zeroinit2X1C1Ev
155*67e74705SXin Li     // CHECK-NEXT: call void @_ZN8zeroinit2X11fEv
156*67e74705SXin Li     X1().f();
157*67e74705SXin Li   }
158*67e74705SXin Li 
159*67e74705SXin Li   template<typename>
160*67e74705SXin Li   struct X2 : X0 {
161*67e74705SXin Li     int x2;
162*67e74705SXin Li     void f();
163*67e74705SXin Li   };
164*67e74705SXin Li 
165*67e74705SXin Li   template<typename>
166*67e74705SXin Li   struct X3 : X2<int> {
X3zeroinit::X3167*67e74705SXin Li     X3() : X2<int>() { }
168*67e74705SXin Li     int i;
169*67e74705SXin Li   };
170*67e74705SXin Li 
171*67e74705SXin Li 
172*67e74705SXin Li   // CHECK-LABEL: define void @_ZN8zeroinit9testX0_X3Ev
testX0_X3()173*67e74705SXin Li   void testX0_X3() {
174*67e74705SXin Li     // CHECK-NOT: call void @llvm.memset
175*67e74705SXin Li     // CHECK: call void @_ZN8zeroinit2X3IiEC1Ev
176*67e74705SXin Li     // CHECK: call void @_ZN8zeroinit2X2IiE1fEv
177*67e74705SXin Li     // CHECK-NEXT: ret void
178*67e74705SXin Li     X3<int>().f();
179*67e74705SXin Li   }
180*67e74705SXin Li 
181*67e74705SXin Li   // More checks at EOF
182*67e74705SXin Li }
183*67e74705SXin Li 
184*67e74705SXin Li namespace PR8726 {
185*67e74705SXin Li class C;
186*67e74705SXin Li struct S {
187*67e74705SXin Li   const C &c1;
188*67e74705SXin Li   int i;
189*67e74705SXin Li   const C &c2;
190*67e74705SXin Li };
f(const C & c)191*67e74705SXin Li void f(const C& c) {
192*67e74705SXin Li   S s = {c, 42, c};
193*67e74705SXin Li }
194*67e74705SXin Li 
195*67e74705SXin Li }
196*67e74705SXin Li 
197*67e74705SXin Li // rdar://problem/9355931
198*67e74705SXin Li namespace test6 {
199*67e74705SXin Li   struct A { A(); A(int); };
200*67e74705SXin Li 
test()201*67e74705SXin Li   void test() {
202*67e74705SXin Li     A arr[10][20] = { 5 };
203*67e74705SXin Li   };
204*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN5test64testEv()
205*67e74705SXin Li   // CHECK:      [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]],
206*67e74705SXin Li 
207*67e74705SXin Li   // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0
208*67e74705SXin Li   // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 0, i64 0
209*67e74705SXin Li   // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5)
210*67e74705SXin Li   // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 1
211*67e74705SXin Li   // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 20
212*67e74705SXin Li   // CHECK-NEXT: br label
213*67e74705SXin Li   // CHECK:      [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
214*67e74705SXin Li   // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]])
215*67e74705SXin Li   // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
216*67e74705SXin Li   // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
217*67e74705SXin Li   // CHECK-NEXT: br i1
218*67e74705SXin Li 
219*67e74705SXin Li   // CHECK:      [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 1
220*67e74705SXin Li   // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 10
221*67e74705SXin Li   // CHECK-NEXT: br label
222*67e74705SXin Li   // CHECK:      [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
223*67e74705SXin Li 
224*67e74705SXin Li   // Inner loop.
225*67e74705SXin Li   // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i32 0, i32 0
226*67e74705SXin Li   // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[IBEGIN]], i64 20
227*67e74705SXin Li   // CHECK-NEXT: br label
228*67e74705SXin Li   // CHECK:      [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ]
229*67e74705SXin Li   // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]])
230*67e74705SXin Li   // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ICUR]], i64 1
231*67e74705SXin Li   // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]]
232*67e74705SXin Li   // CHECK-NEXT: br i1 [[T0]],
233*67e74705SXin Li 
234*67e74705SXin Li   // CHECK:      [[NEXT]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i64 1
235*67e74705SXin Li   // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]]
236*67e74705SXin Li   // CHECK-NEXT: br i1 [[T0]]
237*67e74705SXin Li   // CHECK:      ret void
238*67e74705SXin Li }
239*67e74705SXin Li 
240*67e74705SXin Li namespace PR11124 {
241*67e74705SXin Li   // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B
242*67e74705SXin Li   struct A { int a; A(); A(int); };
243*67e74705SXin Li   struct B : virtual A { int b; };
244*67e74705SXin Li   struct C : B { C(); };
C()245*67e74705SXin Li   C::C() : A(3), B() {}
246*67e74705SXin Li   // CHECK-LABEL: define void @_ZN7PR111241CC1Ev
247*67e74705SXin Li   // CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 12, i32 8, i1 false)
248*67e74705SXin Li   // CHECK-NEXT: call void @_ZN7PR111241BC2Ev
249*67e74705SXin Li   // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B
250*67e74705SXin Li 
251*67e74705SXin Li   struct B2 : virtual A { int B::*b; };
252*67e74705SXin Li   struct C2 : B2 { C2(); };
C2()253*67e74705SXin Li   C2::C2() : A(3), B2() {}
254*67e74705SXin Li   // CHECK-LABEL: define void @_ZN7PR111242C2C1Ev
255*67e74705SXin Li   // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false)
256*67e74705SXin Li   // CHECK-NEXT: call void @_ZN7PR111242B2C2Ev
257*67e74705SXin Li }
258*67e74705SXin Li 
259*67e74705SXin Li // Ensure we produce an i1 here, and don't assert.
260*67e74705SXin Li // CHECK-LABEL: define void @_Z9r170806_bv(
261*67e74705SXin Li // CHECK: call void @_Z9r170806_ab(i1 zeroext false)
262*67e74705SXin Li void r170806_a(bool b = bool());
r170806_b()263*67e74705SXin Li void r170806_b() { r170806_a(); }
264*67e74705SXin Li 
265*67e74705SXin Li namespace PR20256 {
266*67e74705SXin Li   struct data { int i; };
267*67e74705SXin Li 
268*67e74705SXin Li   template<typename T = int>
g()269*67e74705SXin Li   data g() {
270*67e74705SXin Li     data d; // not value-init
271*67e74705SXin Li     return d;
272*67e74705SXin Li   }
273*67e74705SXin Li   template data g();
274*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN7PR202561gIiEENS_4dataEv(
275*67e74705SXin Li   // CHECK-NOT: store
276*67e74705SXin Li   // CHECK-NOT: memset
277*67e74705SXin Li   // CHECK: }
278*67e74705SXin Li 
279*67e74705SXin Li   template<typename ...T>
h(T...t)280*67e74705SXin Li   data h(T ...t) {
281*67e74705SXin Li     data d(t...); // value-init
282*67e74705SXin Li     return d;
283*67e74705SXin Li   }
284*67e74705SXin Li   template data h();
285*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN7PR202561hIJEEENS_4dataEDpT_(
286*67e74705SXin Li   // CHECK: call void @llvm.memset
287*67e74705SXin Li   // CHECK: }
288*67e74705SXin Li 
289*67e74705SXin Li 
290*67e74705SXin Li   template<typename T = int>
j()291*67e74705SXin Li   data j() {
292*67e74705SXin Li     data d = {}; // value-init
293*67e74705SXin Li     return d;
294*67e74705SXin Li   }
295*67e74705SXin Li   template data j();
296*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN7PR202561jIiEENS_4dataEv(
297*67e74705SXin Li   // CHECK: call void @llvm.memset
298*67e74705SXin Li   // CHECK: }
299*67e74705SXin Li 
f()300*67e74705SXin Li   data f() {
301*67e74705SXin Li     data d; // not value-init
302*67e74705SXin Li     return d;
303*67e74705SXin Li   }
304*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN7PR202561fEv(
305*67e74705SXin Li   // CHECK-NOT: store
306*67e74705SXin Li   // CHECK-NOT: memset
307*67e74705SXin Li   // CHECK: }
308*67e74705SXin Li 
i()309*67e74705SXin Li   data i() {
310*67e74705SXin Li     data d = {}; // value-init
311*67e74705SXin Li     return d;
312*67e74705SXin Li   }
313*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN7PR202561iEv(
314*67e74705SXin Li   // CHECK: call void @llvm.memset
315*67e74705SXin Li   // CHECK: }
316*67e74705SXin Li }
317*67e74705SXin Li 
318*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
319*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i64
320*67e74705SXin Li // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
321*67e74705SXin Li // CHECK-NEXT: ret void
322