1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li namespace std {
4*67e74705SXin Li typedef decltype(sizeof(int)) size_t;
5*67e74705SXin Li
6*67e74705SXin Li // libc++'s implementation
7*67e74705SXin Li template <class _E>
8*67e74705SXin Li class initializer_list
9*67e74705SXin Li {
10*67e74705SXin Li const _E* __begin_;
11*67e74705SXin Li size_t __size_;
12*67e74705SXin Li
initializer_list(const _E * __b,size_t __s)13*67e74705SXin Li initializer_list(const _E* __b, size_t __s)
14*67e74705SXin Li : __begin_(__b),
15*67e74705SXin Li __size_(__s)
16*67e74705SXin Li {}
17*67e74705SXin Li
18*67e74705SXin Li public:
19*67e74705SXin Li typedef _E value_type;
20*67e74705SXin Li typedef const _E& reference;
21*67e74705SXin Li typedef const _E& const_reference;
22*67e74705SXin Li typedef size_t size_type;
23*67e74705SXin Li
24*67e74705SXin Li typedef const _E* iterator;
25*67e74705SXin Li typedef const _E* const_iterator;
26*67e74705SXin Li
initializer_list()27*67e74705SXin Li initializer_list() : __begin_(nullptr), __size_(0) {}
28*67e74705SXin Li
size() const29*67e74705SXin Li size_t size() const {return __size_;}
begin() const30*67e74705SXin Li const _E* begin() const {return __begin_;}
end() const31*67e74705SXin Li const _E* end() const {return __begin_ + __size_;}
32*67e74705SXin Li };
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li struct destroyme1 {
36*67e74705SXin Li ~destroyme1();
37*67e74705SXin Li };
38*67e74705SXin Li struct destroyme2 {
39*67e74705SXin Li ~destroyme2();
40*67e74705SXin Li };
41*67e74705SXin Li struct witharg1 {
42*67e74705SXin Li witharg1(const destroyme1&);
43*67e74705SXin Li ~witharg1();
44*67e74705SXin Li };
45*67e74705SXin Li struct wantslist1 {
46*67e74705SXin Li wantslist1(std::initializer_list<destroyme1>);
47*67e74705SXin Li ~wantslist1();
48*67e74705SXin Li };
49*67e74705SXin Li
50*67e74705SXin Li // CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3]
51*67e74705SXin Li // CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 }
52*67e74705SXin Li std::initializer_list<int> globalInitList1 = {1, 2, 3};
53*67e74705SXin Li
54*67e74705SXin Li namespace thread_local_global_array {
55*67e74705SXin Li // FIXME: We should be able to constant-evaluate this even though the
56*67e74705SXin Li // initializer is not a constant expression (pointers to thread_local
57*67e74705SXin Li // objects aren't really a problem).
58*67e74705SXin Li //
59*67e74705SXin Li // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
60*67e74705SXin Li // CHECK: @_ZGRN25thread_local_global_array1xE_ = internal thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
61*67e74705SXin Li std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
62*67e74705SXin Li }
63*67e74705SXin Li
64*67e74705SXin Li // CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
65*67e74705SXin Li // CHECK: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
66*67e74705SXin Li
67*67e74705SXin Li // CHECK: @_ZN15partly_constant1kE = global i32 0, align 4
68*67e74705SXin Li // CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
69*67e74705SXin Li // CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = internal global {{.*}} zeroinitializer, align 8
70*67e74705SXin Li // CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = internal global [3 x {{.*}}] zeroinitializer, align 8
71*67e74705SXin Li // CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4
72*67e74705SXin Li // CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = internal global [2 x i32] zeroinitializer, align 4
73*67e74705SXin Li // CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
74*67e74705SXin Li
75*67e74705SXin Li // CHECK: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43], align 4
76*67e74705SXin Li // CHECK: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4
77*67e74705SXin Li
78*67e74705SXin Li // CHECK: appending global
79*67e74705SXin Li
80*67e74705SXin Li
81*67e74705SXin Li // thread_local initializer:
82*67e74705SXin Li // CHECK-LABEL: define internal void
83*67e74705SXin Li // CHECK: store i32* getelementptr inbounds ([4 x i32], [4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0),
84*67e74705SXin Li // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
85*67e74705SXin Li // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
86*67e74705SXin Li
87*67e74705SXin Li
88*67e74705SXin Li // CHECK-LABEL: define internal void
89*67e74705SXin Li // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0
90*67e74705SXin Li // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1
91*67e74705SXin Li // CHECK: __cxa_atexit
92*67e74705SXin Li // CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0),
93*67e74705SXin Li // CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 0), align 8
94*67e74705SXin Li // CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 1), align 8
95*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
96*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
97*67e74705SXin Li std::initializer_list<witharg1> globalInitList2 = {
98*67e74705SXin Li witharg1(destroyme1()), witharg1(destroyme1())
99*67e74705SXin Li };
100*67e74705SXin Li
fn1(int i)101*67e74705SXin Li void fn1(int i) {
102*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn1i
103*67e74705SXin Li // temporary array
104*67e74705SXin Li // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
105*67e74705SXin Li // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0
106*67e74705SXin Li // CHECK-NEXT: store i32 1, i32*
107*67e74705SXin Li // CHECK-NEXT: getelementptr
108*67e74705SXin Li // CHECK-NEXT: store
109*67e74705SXin Li // CHECK-NEXT: getelementptr
110*67e74705SXin Li // CHECK-NEXT: load
111*67e74705SXin Li // CHECK-NEXT: store
112*67e74705SXin Li // init the list
113*67e74705SXin Li // CHECK-NEXT: getelementptr
114*67e74705SXin Li // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]*
115*67e74705SXin Li // CHECK-NEXT: store i32*
116*67e74705SXin Li // CHECK-NEXT: getelementptr
117*67e74705SXin Li // CHECK-NEXT: store i{{32|64}} 3
118*67e74705SXin Li std::initializer_list<int> intlist{1, 2, i};
119*67e74705SXin Li }
120*67e74705SXin Li
fn2()121*67e74705SXin Li void fn2() {
122*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn2v
123*67e74705SXin Li void target(std::initializer_list<destroyme1>);
124*67e74705SXin Li // objects should be destroyed before dm2, after call returns
125*67e74705SXin Li // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
126*67e74705SXin Li target({ destroyme1(), destroyme1() });
127*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
128*67e74705SXin Li destroyme2 dm2;
129*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
130*67e74705SXin Li }
131*67e74705SXin Li
fn3()132*67e74705SXin Li void fn3() {
133*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn3v
134*67e74705SXin Li // objects should be destroyed after dm2
135*67e74705SXin Li auto list = { destroyme1(), destroyme1() };
136*67e74705SXin Li destroyme2 dm2;
137*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
138*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
139*67e74705SXin Li }
140*67e74705SXin Li
fn4()141*67e74705SXin Li void fn4() {
142*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn4v
143*67e74705SXin Li void target(std::initializer_list<witharg1>);
144*67e74705SXin Li // objects should be destroyed before dm2, after call returns
145*67e74705SXin Li // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
146*67e74705SXin Li // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
147*67e74705SXin Li target({ witharg1(destroyme1()), witharg1(destroyme1()) });
148*67e74705SXin Li // CHECK: call void @_ZN8witharg1D1Ev
149*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
150*67e74705SXin Li destroyme2 dm2;
151*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
152*67e74705SXin Li }
153*67e74705SXin Li
fn5()154*67e74705SXin Li void fn5() {
155*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn5v
156*67e74705SXin Li // temps should be destroyed before dm2
157*67e74705SXin Li // objects should be destroyed after dm2
158*67e74705SXin Li // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
159*67e74705SXin Li auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
160*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
161*67e74705SXin Li destroyme2 dm2;
162*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
163*67e74705SXin Li // CHECK: call void @_ZN8witharg1D1Ev
164*67e74705SXin Li }
165*67e74705SXin Li
fn6()166*67e74705SXin Li void fn6() {
167*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn6v
168*67e74705SXin Li void target(const wantslist1&);
169*67e74705SXin Li // objects should be destroyed before dm2, after call returns
170*67e74705SXin Li // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
171*67e74705SXin Li // CHECK: call void @_Z6targetRK10wantslist1
172*67e74705SXin Li target({ destroyme1(), destroyme1() });
173*67e74705SXin Li // CHECK: call void @_ZN10wantslist1D1Ev
174*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
175*67e74705SXin Li destroyme2 dm2;
176*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
177*67e74705SXin Li }
178*67e74705SXin Li
fn7()179*67e74705SXin Li void fn7() {
180*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn7v
181*67e74705SXin Li // temps should be destroyed before dm2
182*67e74705SXin Li // object should be destroyed after dm2
183*67e74705SXin Li // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
184*67e74705SXin Li wantslist1 wl = { destroyme1(), destroyme1() };
185*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
186*67e74705SXin Li destroyme2 dm2;
187*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
188*67e74705SXin Li // CHECK: call void @_ZN10wantslist1D1Ev
189*67e74705SXin Li }
190*67e74705SXin Li
fn8()191*67e74705SXin Li void fn8() {
192*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn8v
193*67e74705SXin Li void target(std::initializer_list<std::initializer_list<destroyme1>>);
194*67e74705SXin Li // objects should be destroyed before dm2, after call returns
195*67e74705SXin Li // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
196*67e74705SXin Li std::initializer_list<destroyme1> inner;
197*67e74705SXin Li target({ inner, { destroyme1() } });
198*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
199*67e74705SXin Li // Only one destroy loop, since only one inner init list is directly inited.
200*67e74705SXin Li // CHECK-NOT: call void @_ZN10destroyme1D1Ev
201*67e74705SXin Li destroyme2 dm2;
202*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
203*67e74705SXin Li }
204*67e74705SXin Li
fn9()205*67e74705SXin Li void fn9() {
206*67e74705SXin Li // CHECK-LABEL: define void @_Z3fn9v
207*67e74705SXin Li // objects should be destroyed after dm2
208*67e74705SXin Li std::initializer_list<destroyme1> inner;
209*67e74705SXin Li std::initializer_list<std::initializer_list<destroyme1>> list =
210*67e74705SXin Li { inner, { destroyme1() } };
211*67e74705SXin Li destroyme2 dm2;
212*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
213*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
214*67e74705SXin Li // Only one destroy loop, since only one inner init list is directly inited.
215*67e74705SXin Li // CHECK-NOT: call void @_ZN10destroyme1D1Ev
216*67e74705SXin Li // CHECK: ret void
217*67e74705SXin Li }
218*67e74705SXin Li
219*67e74705SXin Li struct haslist1 {
220*67e74705SXin Li std::initializer_list<int> il;
221*67e74705SXin Li haslist1(int i);
222*67e74705SXin Li };
223*67e74705SXin Li
224*67e74705SXin Li // CHECK-LABEL: define void @_ZN8haslist1C2Ei
haslist1(int i)225*67e74705SXin Li haslist1::haslist1(int i)
226*67e74705SXin Li // CHECK: alloca [3 x i32]
227*67e74705SXin Li // CHECK: store i32 %
228*67e74705SXin Li // CHECK: store i32 2
229*67e74705SXin Li // CHECK: store i32 3
230*67e74705SXin Li : il{i, 2, 3}
231*67e74705SXin Li {
232*67e74705SXin Li destroyme2 dm2;
233*67e74705SXin Li }
234*67e74705SXin Li
235*67e74705SXin Li struct haslist2 {
236*67e74705SXin Li std::initializer_list<destroyme1> il;
237*67e74705SXin Li haslist2();
238*67e74705SXin Li };
239*67e74705SXin Li
240*67e74705SXin Li // CHECK-LABEL: define void @_ZN8haslist2C2Ev
haslist2()241*67e74705SXin Li haslist2::haslist2()
242*67e74705SXin Li : il{destroyme1(), destroyme1()}
243*67e74705SXin Li {
244*67e74705SXin Li destroyme2 dm2;
245*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
246*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
247*67e74705SXin Li }
248*67e74705SXin Li
fn10(int i)249*67e74705SXin Li void fn10(int i) {
250*67e74705SXin Li // CHECK-LABEL: define void @_Z4fn10i
251*67e74705SXin Li // CHECK: alloca [3 x i32]
252*67e74705SXin Li // CHECK: call i8* @_Znw{{[jm]}}
253*67e74705SXin Li // CHECK: store i32 %
254*67e74705SXin Li // CHECK: store i32 2
255*67e74705SXin Li // CHECK: store i32 3
256*67e74705SXin Li // CHECK: store i32*
257*67e74705SXin Li (void) new std::initializer_list<int> {i, 2, 3};
258*67e74705SXin Li }
259*67e74705SXin Li
fn11()260*67e74705SXin Li void fn11() {
261*67e74705SXin Li // CHECK-LABEL: define void @_Z4fn11v
262*67e74705SXin Li (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
263*67e74705SXin Li // CHECK: call void @_ZN10destroyme1D1Ev
264*67e74705SXin Li destroyme2 dm2;
265*67e74705SXin Li // CHECK: call void @_ZN10destroyme2D1Ev
266*67e74705SXin Li }
267*67e74705SXin Li
268*67e74705SXin Li namespace PR12178 {
269*67e74705SXin Li struct string {
270*67e74705SXin Li string(int);
271*67e74705SXin Li ~string();
272*67e74705SXin Li };
273*67e74705SXin Li
274*67e74705SXin Li struct pair {
275*67e74705SXin Li string a;
276*67e74705SXin Li int b;
277*67e74705SXin Li };
278*67e74705SXin Li
279*67e74705SXin Li struct map {
280*67e74705SXin Li map(std::initializer_list<pair>);
281*67e74705SXin Li };
282*67e74705SXin Li
283*67e74705SXin Li map m{ {1, 2}, {3, 4} };
284*67e74705SXin Li }
285*67e74705SXin Li
286*67e74705SXin Li namespace rdar13325066 {
287*67e74705SXin Li struct X { ~X(); };
288*67e74705SXin Li
289*67e74705SXin Li // CHECK-LABEL: define void @_ZN12rdar133250664loopERNS_1XES1_
loop(X & x1,X & x2)290*67e74705SXin Li void loop(X &x1, X &x2) {
291*67e74705SXin Li // CHECK: br label
292*67e74705SXin Li // CHECK: br i1
293*67e74705SXin Li // CHECK: br label
294*67e74705SXin Li // CHECK: call void @_ZN12rdar133250661XD1Ev
295*67e74705SXin Li // CHECK: br label
296*67e74705SXin Li // CHECK: br label
297*67e74705SXin Li // CHECK: call void @_ZN12rdar133250661XD1Ev
298*67e74705SXin Li // CHECK: br i1
299*67e74705SXin Li // CHECK: br label
300*67e74705SXin Li // CHECK: ret void
301*67e74705SXin Li for (X x : { x1, x2 }) { }
302*67e74705SXin Li }
303*67e74705SXin Li }
304*67e74705SXin Li
305*67e74705SXin Li namespace dtors {
306*67e74705SXin Li struct S {
307*67e74705SXin Li S();
308*67e74705SXin Li ~S();
309*67e74705SXin Li };
310*67e74705SXin Li void z();
311*67e74705SXin Li
312*67e74705SXin Li // CHECK-LABEL: define void @_ZN5dtors1fEv(
f()313*67e74705SXin Li void f() {
314*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
315*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
316*67e74705SXin Li std::initializer_list<S>{ S(), S() };
317*67e74705SXin Li
318*67e74705SXin Li // Destruction loop for underlying array.
319*67e74705SXin Li // CHECK: br label
320*67e74705SXin Li // CHECK: call void @_ZN5dtors1SD1Ev(
321*67e74705SXin Li // CHECK: br i1
322*67e74705SXin Li
323*67e74705SXin Li // CHECK: call void @_ZN5dtors1zEv(
324*67e74705SXin Li z();
325*67e74705SXin Li
326*67e74705SXin Li // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
327*67e74705SXin Li }
328*67e74705SXin Li
329*67e74705SXin Li // CHECK-LABEL: define void @_ZN5dtors1gEv(
g()330*67e74705SXin Li void g() {
331*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
332*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
333*67e74705SXin Li auto x = std::initializer_list<S>{ S(), S() };
334*67e74705SXin Li
335*67e74705SXin Li // Destruction loop for underlying array.
336*67e74705SXin Li // CHECK: br label
337*67e74705SXin Li // CHECK: call void @_ZN5dtors1SD1Ev(
338*67e74705SXin Li // CHECK: br i1
339*67e74705SXin Li
340*67e74705SXin Li // CHECK: call void @_ZN5dtors1zEv(
341*67e74705SXin Li z();
342*67e74705SXin Li
343*67e74705SXin Li // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
344*67e74705SXin Li }
345*67e74705SXin Li
346*67e74705SXin Li // CHECK-LABEL: define void @_ZN5dtors1hEv(
h()347*67e74705SXin Li void h() {
348*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
349*67e74705SXin Li // CHECK: call void @_ZN5dtors1SC1Ev(
350*67e74705SXin Li std::initializer_list<S> x = { S(), S() };
351*67e74705SXin Li
352*67e74705SXin Li // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
353*67e74705SXin Li
354*67e74705SXin Li // CHECK: call void @_ZN5dtors1zEv(
355*67e74705SXin Li z();
356*67e74705SXin Li
357*67e74705SXin Li // Destruction loop for underlying array.
358*67e74705SXin Li // CHECK: br label
359*67e74705SXin Li // CHECK: call void @_ZN5dtors1SD1Ev(
360*67e74705SXin Li // CHECK: br i1
361*67e74705SXin Li }
362*67e74705SXin Li }
363*67e74705SXin Li
364*67e74705SXin Li namespace partly_constant {
365*67e74705SXin Li int k;
366*67e74705SXin Li std::initializer_list<std::initializer_list<int>> &&il = { { 1, 2, 3 }, { 4, k }, { 5, 6, 7, 8 } };
367*67e74705SXin Li // First init list.
368*67e74705SXin Li // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
369*67e74705SXin Li // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_FIRST]], i64 0, i64 0),
370*67e74705SXin Li // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 0)
371*67e74705SXin Li // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 1)
372*67e74705SXin Li // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
373*67e74705SXin Li //
374*67e74705SXin Li // Second init list array (non-constant).
375*67e74705SXin Li // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0)
376*67e74705SXin Li // CHECK: load i32, i32* @_ZN15partly_constant1kE
377*67e74705SXin Li // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 1)
378*67e74705SXin Li //
379*67e74705SXin Li // Second init list.
380*67e74705SXin Li // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0),
381*67e74705SXin Li // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 0)
382*67e74705SXin Li // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 1)
383*67e74705SXin Li //
384*67e74705SXin Li // Third init list.
385*67e74705SXin Li // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
386*67e74705SXin Li // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0),
387*67e74705SXin Li // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0)
388*67e74705SXin Li // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1)
389*67e74705SXin Li // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
390*67e74705SXin Li //
391*67e74705SXin Li // Outer init list.
392*67e74705SXin Li // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0),
393*67e74705SXin Li // CHECK: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 0)
394*67e74705SXin Li // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 1)
395*67e74705SXin Li //
396*67e74705SXin Li // 'il' reference.
397*67e74705SXin Li // CHECK: store {{.*}}* @[[PARTLY_CONSTANT_OUTER]], {{.*}}** @_ZN15partly_constant2ilE, align 8
398*67e74705SXin Li }
399*67e74705SXin Li
400*67e74705SXin Li namespace nested {
401*67e74705SXin Li struct A { A(); ~A(); };
402*67e74705SXin Li struct B { const A &a; ~B(); };
403*67e74705SXin Li struct C { std::initializer_list<B> b; ~C(); };
404*67e74705SXin Li void f();
405*67e74705SXin Li // CHECK-LABEL: define void @_ZN6nested1gEv(
g()406*67e74705SXin Li void g() {
407*67e74705SXin Li // CHECK: call void @_ZN6nested1AC1Ev(
408*67e74705SXin Li // CHECK-NOT: call
409*67e74705SXin Li // CHECK: call void @_ZN6nested1AC1Ev(
410*67e74705SXin Li // CHECK-NOT: call
411*67e74705SXin Li const C &c { { { A() }, { A() } } };
412*67e74705SXin Li
413*67e74705SXin Li // CHECK: call void @_ZN6nested1fEv(
414*67e74705SXin Li // CHECK-NOT: call
415*67e74705SXin Li f();
416*67e74705SXin Li
417*67e74705SXin Li // CHECK: call void @_ZN6nested1CD1Ev(
418*67e74705SXin Li // CHECK-NOT: call
419*67e74705SXin Li
420*67e74705SXin Li // Destroy B[2] array.
421*67e74705SXin Li // FIXME: This isn't technically correct: reverse construction order would
422*67e74705SXin Li // destroy the second B then the second A then the first B then the first A.
423*67e74705SXin Li // CHECK: call void @_ZN6nested1BD1Ev(
424*67e74705SXin Li // CHECK-NOT: call
425*67e74705SXin Li // CHECK: br
426*67e74705SXin Li
427*67e74705SXin Li // CHECK-NOT: call
428*67e74705SXin Li // CHECK: call void @_ZN6nested1AD1Ev(
429*67e74705SXin Li // CHECK-NOT: call
430*67e74705SXin Li // CHECK: call void @_ZN6nested1AD1Ev(
431*67e74705SXin Li // CHECK-NOT: call
432*67e74705SXin Li // CHECK: }
433*67e74705SXin Li }
434*67e74705SXin Li }
435*67e74705SXin Li
436*67e74705SXin Li namespace DR1070 {
437*67e74705SXin Li struct A {
438*67e74705SXin Li A(std::initializer_list<int>);
439*67e74705SXin Li };
440*67e74705SXin Li struct B {
441*67e74705SXin Li int i;
442*67e74705SXin Li A a;
443*67e74705SXin Li };
444*67e74705SXin Li B b = {1};
445*67e74705SXin Li struct C {
446*67e74705SXin Li std::initializer_list<int> a;
447*67e74705SXin Li B b;
448*67e74705SXin Li std::initializer_list<double> c;
449*67e74705SXin Li };
450*67e74705SXin Li C c = {};
451*67e74705SXin Li }
452*67e74705SXin Li
453*67e74705SXin Li namespace ArrayOfInitList {
454*67e74705SXin Li struct S {
455*67e74705SXin Li S(std::initializer_list<int>);
456*67e74705SXin Li };
457*67e74705SXin Li S x[1] = {};
458*67e74705SXin Li }
459*67e74705SXin Li
460*67e74705SXin Li namespace PR20445 {
461*67e74705SXin Li struct vector { vector(std::initializer_list<int>); };
462*67e74705SXin Li struct MyClass { explicit MyClass(const vector &v); };
f()463*67e74705SXin Li template<int x> void f() { new MyClass({42, 43}); }
464*67e74705SXin Li template void f<0>();
465*67e74705SXin Li // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
466*67e74705SXin Li // CHECK: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @[[REFTMP1]], i64 0, i64 0)
467*67e74705SXin Li // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
468*67e74705SXin Li // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
469*67e74705SXin Li }
470*67e74705SXin Li
471*67e74705SXin Li namespace ConstExpr {
472*67e74705SXin Li class C {
473*67e74705SXin Li int x;
474*67e74705SXin Li public:
C(int x)475*67e74705SXin Li constexpr C(int x) : x(x) {}
476*67e74705SXin Li };
477*67e74705SXin Li void f(std::initializer_list<C>);
g()478*67e74705SXin Li void g() {
479*67e74705SXin Li // CHECK-LABEL: _ZN9ConstExpr1gEv
480*67e74705SXin Li // CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x %"class.ConstExpr::C"], [3 x %"class.ConstExpr::C"]* @[[REFTMP2]], i64 0, i64 0)
481*67e74705SXin Li // CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE
482*67e74705SXin Li f({C(1), C(2), C(3)});
483*67e74705SXin Li }
484*67e74705SXin Li }
485*67e74705SXin Li
486*67e74705SXin Li namespace B19773010 {
487*67e74705SXin Li template <class T1, class T2> struct pair {
488*67e74705SXin Li T1 first;
489*67e74705SXin Li T2 second;
pairB19773010::pair490*67e74705SXin Li constexpr pair() : first(), second() {}
pairB19773010::pair491*67e74705SXin Li constexpr pair(T1 a, T2 b) : first(a), second(b) {}
492*67e74705SXin Li };
493*67e74705SXin Li
494*67e74705SXin Li enum E { ENUM_CONSTANT };
495*67e74705SXin Li struct testcase {
496*67e74705SXin Li testcase(std::initializer_list<pair<const char *, E>>);
497*67e74705SXin Li };
f1()498*67e74705SXin Li void f1() {
499*67e74705SXin Li // CHECK-LABEL: @_ZN9B197730102f1Ev
500*67e74705SXin Li testcase a{{"", ENUM_CONSTANT}};
501*67e74705SXin Li // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
502*67e74705SXin Li }
f2()503*67e74705SXin Li void f2() {
504*67e74705SXin Li // CHECK-LABEL: @_ZN9B197730102f2Ev
505*67e74705SXin Li // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 16
506*67e74705SXin Li static std::initializer_list<pair<const char *, E>> a, p[2] =
507*67e74705SXin Li {a, {{"", ENUM_CONSTANT}}};
508*67e74705SXin Li }
509*67e74705SXin Li
PR22940_helper(const pair<void *,int> &)510*67e74705SXin Li void PR22940_helper(const pair<void*, int>&) { }
PR22940()511*67e74705SXin Li void PR22940() {
512*67e74705SXin Li // CHECK-LABEL: @_ZN9B197730107PR22940Ev
513*67e74705SXin Li // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
514*67e74705SXin Li // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE(
515*67e74705SXin Li PR22940_helper(pair<void*, int>());
516*67e74705SXin Li }
517*67e74705SXin Li }
518