blob: 8adb887b9a8f207d4bb7b940523b870a316c7b0f [file] [log] [blame]
David Blaikie1b76fbc2012-09-10 23:06:08 +00001// RUN: %clang_cc1 -std=c++11 -S -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
Richard Smith7c3e6152013-06-12 22:31:48 +000050// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3]
51// 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
Richard Smith3282b842013-06-14 03:07:01 +000060 // CHECK: @_ZGRN25thread_local_global_array1xE = private 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
65// CHECK: @_ZGR15globalInitList2 = private 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
69// CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = private global {{.*}} zeroinitializer, align 8
70// CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = private global [3 x {{.*}}] zeroinitializer, align 8
71// CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = private constant [3 x i32] [i32 1, i32 2, i32 3], align 4
72// CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = private global [2 x i32] zeroinitializer, align 4
73// CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = private constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
74
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000075// CHECK: appending global
Richard Smith7c3e6152013-06-12 22:31:48 +000076
77
78// thread_local initializer:
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000079// CHECK: define internal void
Richard Smith7c3e6152013-06-12 22:31:48 +000080// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0),
81// 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
85// CHECK: define internal void
86// 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
Richard Smith7c3e6152013-06-12 22:31:48 +000089// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i64 0, i64 0),
90// 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) {
99 // CHECK: define void @_Z3fn1i
100 // 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() {
119 // CHECK: define void @_Z3fn2v
120 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() {
130 // CHECK: define void @_Z3fn3v
131 // 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() {
139 // CHECK: define void @_Z3fn4v
140 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() {
152 // CHECK: define void @_Z3fn5v
153 // 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() {
164 // CHECK: define void @_Z3fn6v
165 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() {
177 // CHECK: define void @_Z3fn7v
178 // 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() {
189 // CHECK: define void @_Z3fn8v
190 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() {
203 // CHECK: define void @_Z3fn9v
204 // 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
221// CHECK: define void @_ZN8haslist1C2Ev
222haslist1::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
238// CHECK: define void @_ZN8haslist2C2Ev
239haslist2::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() {
248 // CHECK: define void @_Z4fn10v
249 // 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() {
260 // CHECK: define void @_Z4fn11v
261 (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
288 // CHECK: define void @_ZN12rdar133250664loopERNS_1XES1_
289 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
311 // CHECK: 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
328 // CHECK: 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
345 // CHECK: define void @_ZN5dtors1hEv(
346 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)
387 // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZGRN15partly_constant2ilE4, i64 0, i64 2, i32 1)
388 // 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}