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