blob: 79644cd3d0152977c667b835eaecc3131ed95393 [file] [log] [blame]
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001// RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
Sebastian Redl32cf1f22012-02-17 08:42:25 +00002
3namespace std {
4 typedef decltype(sizeof(int)) size_t;
5
6 // libc++'s implementation
7 template <class _E>
8 class initializer_list
9 {
10 const _E* __begin_;
11 size_t __size_;
12
13 initializer_list(const _E* __b, size_t __s)
14 : __begin_(__b),
15 __size_(__s)
16 {}
17
18 public:
19 typedef _E value_type;
20 typedef const _E& reference;
21 typedef const _E& const_reference;
22 typedef size_t size_type;
23
24 typedef const _E* iterator;
25 typedef const _E* const_iterator;
26
27 initializer_list() : __begin_(nullptr), __size_(0) {}
28
29 size_t size() const {return __size_;}
30 const _E* begin() const {return __begin_;}
31 const _E* end() const {return __begin_ + __size_;}
32 };
33}
34
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000035struct destroyme1 {
36 ~destroyme1();
37};
38struct destroyme2 {
39 ~destroyme2();
40};
41struct witharg1 {
42 witharg1(const destroyme1&);
43 ~witharg1();
44};
45struct wantslist1 {
46 wantslist1(std::initializer_list<destroyme1>);
47 ~wantslist1();
48};
49
Stephen Hines0e2c34f2015-03-23 12:09:02 -070050// CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3]
Stephen Hines6bcf27b2014-05-29 04:14:42 -070051// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 }
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000052std::initializer_list<int> globalInitList1 = {1, 2, 3};
53
Richard Smith04e51762013-04-14 23:01:42 +000054namespace thread_local_global_array {
Richard Smith7c3e6152013-06-12 22:31:48 +000055 // FIXME: We should be able to constant-evaluate this even though the
56 // initializer is not a constant expression (pointers to thread_local
57 // objects aren't really a problem).
58 //
59 // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
Stephen Hines0e2c34f2015-03-23 12:09:02 -070060 // CHECK: @_ZGRN25thread_local_global_array1xE_ = internal thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
Richard Smith04e51762013-04-14 23:01:42 +000061 std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
62}
63
Richard Smith7c3e6152013-06-12 22:31:48 +000064// CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
Stephen Hines0e2c34f2015-03-23 12:09:02 -070065// CHECK: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
Richard Smith3282b842013-06-14 03:07:01 +000066
67// CHECK: @_ZN15partly_constant1kE = global i32 0, align 4
68// CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
Stephen Hines0e2c34f2015-03-23 12:09:02 -070069// CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = internal global {{.*}} zeroinitializer, align 8
70// CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = internal global [3 x {{.*}}] zeroinitializer, align 8
71// CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4
72// CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = internal global [2 x i32] zeroinitializer, align 4
73// CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
Richard Smith3282b842013-06-14 03:07:01 +000074
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000075// CHECK: appending global
Richard Smith7c3e6152013-06-12 22:31:48 +000076
77
78// thread_local initializer:
Stephen Lin93ab6bf2013-08-15 06:47:53 +000079// CHECK-LABEL: define internal void
Stephen Hines6bcf27b2014-05-29 04:14:42 -070080// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0),
Richard Smith7c3e6152013-06-12 22:31:48 +000081// CHECK: i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
82// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
83
84
Stephen Lin93ab6bf2013-08-15 06:47:53 +000085// CHECK-LABEL: define internal void
Stephen Hines6bcf27b2014-05-29 04:14:42 -070086// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0
87// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000088// CHECK: __cxa_atexit
Stephen Hines6bcf27b2014-05-29 04:14:42 -070089// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0),
Richard Smith7c3e6152013-06-12 22:31:48 +000090// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8
91// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000092// CHECK: call void @_ZN10destroyme1D1Ev
93// CHECK: call void @_ZN10destroyme1D1Ev
94std::initializer_list<witharg1> globalInitList2 = {
95 witharg1(destroyme1()), witharg1(destroyme1())
96};
97
Sebastian Redl32cf1f22012-02-17 08:42:25 +000098void fn1(int i) {
Stephen Lin93ab6bf2013-08-15 06:47:53 +000099 // CHECK-LABEL: define void @_Z3fn1i
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000100 // temporary array
101 // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
102 // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0
103 // CHECK-NEXT: store i32 1, i32*
104 // CHECK-NEXT: getelementptr
105 // CHECK-NEXT: store
106 // CHECK-NEXT: getelementptr
107 // CHECK-NEXT: load
108 // CHECK-NEXT: store
109 // init the list
110 // CHECK-NEXT: getelementptr
111 // CHECK-NEXT: getelementptr inbounds [3 x i32]*
112 // CHECK-NEXT: store i32*
113 // CHECK-NEXT: getelementptr
114 // CHECK-NEXT: store i{{32|64}} 3
115 std::initializer_list<int> intlist{1, 2, i};
116}
117
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000118void fn2() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000119 // CHECK-LABEL: define void @_Z3fn2v
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000120 void target(std::initializer_list<destroyme1>);
121 // objects should be destroyed before dm2, after call returns
Sebastian Redl25e640a2012-02-19 12:27:51 +0000122 // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000123 target({ destroyme1(), destroyme1() });
124 // CHECK: call void @_ZN10destroyme1D1Ev
125 destroyme2 dm2;
126 // CHECK: call void @_ZN10destroyme2D1Ev
127}
128
129void fn3() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000130 // CHECK-LABEL: define void @_Z3fn3v
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000131 // objects should be destroyed after dm2
132 auto list = { destroyme1(), destroyme1() };
133 destroyme2 dm2;
134 // CHECK: call void @_ZN10destroyme2D1Ev
135 // CHECK: call void @_ZN10destroyme1D1Ev
136}
Sebastian Redl25e640a2012-02-19 12:27:51 +0000137
138void fn4() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000139 // CHECK-LABEL: define void @_Z3fn4v
Sebastian Redl25e640a2012-02-19 12:27:51 +0000140 void target(std::initializer_list<witharg1>);
141 // objects should be destroyed before dm2, after call returns
142 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
143 // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
144 target({ witharg1(destroyme1()), witharg1(destroyme1()) });
145 // CHECK: call void @_ZN8witharg1D1Ev
146 // CHECK: call void @_ZN10destroyme1D1Ev
147 destroyme2 dm2;
148 // CHECK: call void @_ZN10destroyme2D1Ev
149}
150
151void fn5() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000152 // CHECK-LABEL: define void @_Z3fn5v
Sebastian Redl25e640a2012-02-19 12:27:51 +0000153 // temps should be destroyed before dm2
154 // objects should be destroyed after dm2
155 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
156 auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
157 // CHECK: call void @_ZN10destroyme1D1Ev
158 destroyme2 dm2;
159 // CHECK: call void @_ZN10destroyme2D1Ev
160 // CHECK: call void @_ZN8witharg1D1Ev
161}
Sebastian Redlbac5cf42012-02-19 12:27:56 +0000162
163void fn6() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000164 // CHECK-LABEL: define void @_Z3fn6v
Sebastian Redlbac5cf42012-02-19 12:27:56 +0000165 void target(const wantslist1&);
166 // objects should be destroyed before dm2, after call returns
167 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
168 // CHECK: call void @_Z6targetRK10wantslist1
169 target({ destroyme1(), destroyme1() });
170 // CHECK: call void @_ZN10wantslist1D1Ev
171 // CHECK: call void @_ZN10destroyme1D1Ev
172 destroyme2 dm2;
173 // CHECK: call void @_ZN10destroyme2D1Ev
174}
175
176void fn7() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000177 // CHECK-LABEL: define void @_Z3fn7v
Sebastian Redlbac5cf42012-02-19 12:27:56 +0000178 // temps should be destroyed before dm2
179 // object should be destroyed after dm2
180 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
181 wantslist1 wl = { destroyme1(), destroyme1() };
182 // CHECK: call void @_ZN10destroyme1D1Ev
183 destroyme2 dm2;
184 // CHECK: call void @_ZN10destroyme2D1Ev
185 // CHECK: call void @_ZN10wantslist1D1Ev
186}
Sebastian Redlaf130fd2012-02-19 12:28:02 +0000187
188void fn8() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000189 // CHECK-LABEL: define void @_Z3fn8v
Sebastian Redlaf130fd2012-02-19 12:28:02 +0000190 void target(std::initializer_list<std::initializer_list<destroyme1>>);
191 // objects should be destroyed before dm2, after call returns
192 // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
193 std::initializer_list<destroyme1> inner;
194 target({ inner, { destroyme1() } });
195 // CHECK: call void @_ZN10destroyme1D1Ev
196 // Only one destroy loop, since only one inner init list is directly inited.
197 // CHECK-NOT: call void @_ZN10destroyme1D1Ev
198 destroyme2 dm2;
199 // CHECK: call void @_ZN10destroyme2D1Ev
200}
201
202void fn9() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000203 // CHECK-LABEL: define void @_Z3fn9v
Sebastian Redlaf130fd2012-02-19 12:28:02 +0000204 // objects should be destroyed after dm2
205 std::initializer_list<destroyme1> inner;
206 std::initializer_list<std::initializer_list<destroyme1>> list =
207 { inner, { destroyme1() } };
208 destroyme2 dm2;
209 // CHECK: call void @_ZN10destroyme2D1Ev
210 // CHECK: call void @_ZN10destroyme1D1Ev
211 // Only one destroy loop, since only one inner init list is directly inited.
212 // CHECK-NOT: call void @_ZN10destroyme1D1Ev
213 // CHECK: ret void
214}
Sebastian Redl924db712012-02-19 15:41:54 +0000215
216struct haslist1 {
217 std::initializer_list<int> il;
218 haslist1();
219};
220
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000221// CHECK-LABEL: define void @_ZN8haslist1C2Ev
Sebastian Redl924db712012-02-19 15:41:54 +0000222haslist1::haslist1()
223// CHECK: alloca [3 x i32]
224// CHECK: store i32 1
225// CHECK: store i32 2
226// CHECK: store i32 3
227// CHECK: store i{{32|64}} 3
228 : il{1, 2, 3}
229{
230 destroyme2 dm2;
231}
232
233struct haslist2 {
234 std::initializer_list<destroyme1> il;
235 haslist2();
236};
237
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000238// CHECK-LABEL: define void @_ZN8haslist2C2Ev
Sebastian Redl924db712012-02-19 15:41:54 +0000239haslist2::haslist2()
240 : il{destroyme1(), destroyme1()}
241{
242 destroyme2 dm2;
243 // CHECK: call void @_ZN10destroyme2D1Ev
244 // CHECK: call void @_ZN10destroyme1D1Ev
245}
Sebastian Redl972edf02012-02-19 16:03:09 +0000246
247void fn10() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000248 // CHECK-LABEL: define void @_Z4fn10v
Sebastian Redl972edf02012-02-19 16:03:09 +0000249 // CHECK: alloca [3 x i32]
Benjamin Kramer4b45d7f2012-02-19 16:20:58 +0000250 // CHECK: call noalias i8* @_Znw{{[jm]}}
Sebastian Redl972edf02012-02-19 16:03:09 +0000251 // CHECK: store i32 1
252 // CHECK: store i32 2
253 // CHECK: store i32 3
254 // CHECK: store i32*
255 // CHECK: store i{{32|64}} 3
256 (void) new std::initializer_list<int> {1, 2, 3};
257}
258
259void fn11() {
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000260 // CHECK-LABEL: define void @_Z4fn11v
Sebastian Redl972edf02012-02-19 16:03:09 +0000261 (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
262 // CHECK: call void @_ZN10destroyme1D1Ev
263 destroyme2 dm2;
264 // CHECK: call void @_ZN10destroyme2D1Ev
265}
Sebastian Redl28357452012-03-05 19:35:43 +0000266
267namespace PR12178 {
268 struct string {
269 string(int);
270 ~string();
271 };
272
273 struct pair {
274 string a;
275 int b;
276 };
277
278 struct map {
279 map(std::initializer_list<pair>);
280 };
281
282 map m{ {1, 2}, {3, 4} };
283}
Douglas Gregor29a11f42013-04-06 00:46:20 +0000284
285namespace rdar13325066 {
286 struct X { ~X(); };
287
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000288 // CHECK-LABEL: define void @_ZN12rdar133250664loopERNS_1XES1_
Douglas Gregor29a11f42013-04-06 00:46:20 +0000289 void loop(X &x1, X &x2) {
290 // CHECK: br label
291 // CHECK: br i1
292 // CHECK: br label
293 // CHECK call void @_ZN12rdar133250661XD1Ev
294 // CHECK: br label
295 // CHECK: br label
296 // CHECK: call void @_ZN12rdar133250661XD1Ev
297 // CHECK: br i1
298 // CHECK: br label
299 // CHECK: ret void
300 for (X x : { x1, x2 }) { }
301 }
302}
Richard Smithe69fb202013-05-23 21:54:14 +0000303
304namespace dtors {
305 struct S {
306 S();
307 ~S();
308 };
Richard Smith7c3e6152013-06-12 22:31:48 +0000309 void z();
310
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000311 // CHECK-LABEL: define void @_ZN5dtors1fEv(
Richard Smithe69fb202013-05-23 21:54:14 +0000312 void f() {
Richard Smith7b7db262013-06-13 18:07:12 +0000313 // CHECK: call void @_ZN5dtors1SC1Ev(
314 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smithe69fb202013-05-23 21:54:14 +0000315 std::initializer_list<S>{ S(), S() };
Richard Smith7c3e6152013-06-12 22:31:48 +0000316
317 // Destruction loop for underlying array.
318 // CHECK: br label
319 // CHECK: call void @_ZN5dtors1SD1Ev(
320 // CHECK: br i1
321
322 // CHECK: call void @_ZN5dtors1zEv(
323 z();
324
325 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
Richard Smithe69fb202013-05-23 21:54:14 +0000326 }
Richard Smith7c3e6152013-06-12 22:31:48 +0000327
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000328 // CHECK-LABEL: define void @_ZN5dtors1gEv(
Richard Smith211c8dd2013-06-05 00:46:14 +0000329 void g() {
Richard Smith7b7db262013-06-13 18:07:12 +0000330 // CHECK: call void @_ZN5dtors1SC1Ev(
331 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smith211c8dd2013-06-05 00:46:14 +0000332 auto x = std::initializer_list<S>{ S(), S() };
Richard Smith7c3e6152013-06-12 22:31:48 +0000333
334 // Destruction loop for underlying array.
335 // CHECK: br label
336 // CHECK: call void @_ZN5dtors1SD1Ev(
337 // CHECK: br i1
338
339 // CHECK: call void @_ZN5dtors1zEv(
340 z();
341
342 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
343 }
344
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000345 // CHECK-LABEL: define void @_ZN5dtors1hEv(
Richard Smith7c3e6152013-06-12 22:31:48 +0000346 void h() {
Richard Smith7b7db262013-06-13 18:07:12 +0000347 // CHECK: call void @_ZN5dtors1SC1Ev(
348 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smith7c3e6152013-06-12 22:31:48 +0000349 std::initializer_list<S> x = { S(), S() };
350
351 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
352
353 // CHECK: call void @_ZN5dtors1zEv(
354 z();
355
356 // Destruction loop for underlying array.
357 // CHECK: br label
358 // CHECK: call void @_ZN5dtors1SD1Ev(
359 // CHECK: br i1
Richard Smith211c8dd2013-06-05 00:46:14 +0000360 }
Richard Smithe69fb202013-05-23 21:54:14 +0000361}
Richard Smith3282b842013-06-14 03:07:01 +0000362
363namespace partly_constant {
364 int k;
365 std::initializer_list<std::initializer_list<int>> &&il = { { 1, 2, 3 }, { 4, k }, { 5, 6, 7, 8 } };
366 // First init list.
367 // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
368 // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_FIRST]], i64 0, i64 0),
369 // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 0)
370 // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 1)
371 // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
372 //
373 // Second init list array (non-constant).
374 // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0)
375 // CHECK: load i32* @_ZN15partly_constant1kE
376 // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 1)
377 //
378 // Second init list.
379 // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0),
380 // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 0)
381 // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 1)
382 //
383 // Third init list.
384 // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
385 // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0),
386 // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700387 // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1)
Richard Smith3282b842013-06-14 03:07:01 +0000388 // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
389 //
390 // Outer init list.
391 // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0),
392 // CHECK: {{.*}}** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 0)
393 // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 1)
394 //
395 // 'il' reference.
396 // CHECK: store {{.*}}* @[[PARTLY_CONSTANT_OUTER]], {{.*}}** @_ZN15partly_constant2ilE, align 8
397}
Richard Smith5771aab2013-06-27 22:54:33 +0000398
399namespace nested {
400 struct A { A(); ~A(); };
401 struct B { const A &a; ~B(); };
402 struct C { std::initializer_list<B> b; ~C(); };
403 void f();
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000404 // CHECK-LABEL: define void @_ZN6nested1gEv(
Richard Smith5771aab2013-06-27 22:54:33 +0000405 void g() {
406 // CHECK: call void @_ZN6nested1AC1Ev(
407 // CHECK-NOT: call
408 // CHECK: call void @_ZN6nested1AC1Ev(
409 // CHECK-NOT: call
410 const C &c { { { A() }, { A() } } };
411
412 // CHECK: call void @_ZN6nested1fEv(
413 // CHECK-NOT: call
414 f();
415
416 // CHECK: call void @_ZN6nested1CD1Ev(
417 // CHECK-NOT: call
418
419 // Destroy B[2] array.
420 // FIXME: This isn't technically correct: reverse construction order would
421 // destroy the second B then the second A then the first B then the first A.
422 // CHECK: call void @_ZN6nested1BD1Ev(
423 // CHECK-NOT: call
424 // CHECK: br
425
426 // CHECK-NOT: call
427 // CHECK: call void @_ZN6nested1AD1Ev(
428 // CHECK-NOT: call
429 // CHECK: call void @_ZN6nested1AD1Ev(
430 // CHECK-NOT: call
431 // CHECK: }
432 }
433}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700434
435namespace DR1070 {
436 struct A {
437 A(std::initializer_list<int>);
438 };
439 struct B {
440 int i;
441 A a;
442 };
443 B b = {1};
444 struct C {
445 std::initializer_list<int> a;
446 B b;
447 std::initializer_list<double> c;
448 };
449 C c = {};
450}
451
452namespace ArrayOfInitList {
453 struct S {
454 S(std::initializer_list<int>);
455 };
456 S x[1] = {};
457}
Stephen Hines176edba2014-12-01 14:53:08 -0800458
459namespace PR20445 {
460 struct vector { vector(std::initializer_list<int>); };
461 struct MyClass { explicit MyClass(const vector &v); };
462 template<int x> void f() { new MyClass({42, 43}); }
463 template void f<0>();
464 // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
465 // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
466 // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
467}