blob: 1156a165c9f572fb2de569a1ab9698dd03782934 [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
60 // CHECK: @_ZGRN25thread_local_global_array1xE = private thread_local global [4 x i32]
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
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000066// CHECK: appending global
Richard Smith7c3e6152013-06-12 22:31:48 +000067
68
69// thread_local initializer:
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000070// CHECK: define internal void
Richard Smith7c3e6152013-06-12 22:31:48 +000071// CHECK: store i32 1, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0)
72// CHECK: store i32 2, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 1)
73// CHECK: store i32 3, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 2)
74// CHECK: store i32 4, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 3)
75// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0),
76// CHECK: i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
77// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
78
79
80// CHECK: define internal void
81// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 0
82// 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 +000083// CHECK: __cxa_atexit
Richard Smith7c3e6152013-06-12 22:31:48 +000084// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i64 0, i64 0),
85// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8
86// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8
Sebastian Redl19b1a6e2012-02-25 20:51:20 +000087// CHECK: call void @_ZN10destroyme1D1Ev
88// CHECK: call void @_ZN10destroyme1D1Ev
89std::initializer_list<witharg1> globalInitList2 = {
90 witharg1(destroyme1()), witharg1(destroyme1())
91};
92
Sebastian Redl32cf1f22012-02-17 08:42:25 +000093void fn1(int i) {
94 // CHECK: define void @_Z3fn1i
95 // temporary array
96 // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
97 // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0
98 // CHECK-NEXT: store i32 1, i32*
99 // CHECK-NEXT: getelementptr
100 // CHECK-NEXT: store
101 // CHECK-NEXT: getelementptr
102 // CHECK-NEXT: load
103 // CHECK-NEXT: store
104 // init the list
105 // CHECK-NEXT: getelementptr
106 // CHECK-NEXT: getelementptr inbounds [3 x i32]*
107 // CHECK-NEXT: store i32*
108 // CHECK-NEXT: getelementptr
109 // CHECK-NEXT: store i{{32|64}} 3
110 std::initializer_list<int> intlist{1, 2, i};
111}
112
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000113void fn2() {
114 // CHECK: define void @_Z3fn2v
115 void target(std::initializer_list<destroyme1>);
116 // objects should be destroyed before dm2, after call returns
Sebastian Redl25e640a2012-02-19 12:27:51 +0000117 // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
Sebastian Redl32cf1f22012-02-17 08:42:25 +0000118 target({ destroyme1(), destroyme1() });
119 // CHECK: call void @_ZN10destroyme1D1Ev
120 destroyme2 dm2;
121 // CHECK: call void @_ZN10destroyme2D1Ev
122}
123
124void fn3() {
125 // CHECK: define void @_Z3fn3v
126 // objects should be destroyed after dm2
127 auto list = { destroyme1(), destroyme1() };
128 destroyme2 dm2;
129 // CHECK: call void @_ZN10destroyme2D1Ev
130 // CHECK: call void @_ZN10destroyme1D1Ev
131}
Sebastian Redl25e640a2012-02-19 12:27:51 +0000132
133void fn4() {
134 // CHECK: define void @_Z3fn4v
135 void target(std::initializer_list<witharg1>);
136 // objects should be destroyed before dm2, after call returns
137 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
138 // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
139 target({ witharg1(destroyme1()), witharg1(destroyme1()) });
140 // CHECK: call void @_ZN8witharg1D1Ev
141 // CHECK: call void @_ZN10destroyme1D1Ev
142 destroyme2 dm2;
143 // CHECK: call void @_ZN10destroyme2D1Ev
144}
145
146void fn5() {
147 // CHECK: define void @_Z3fn5v
148 // temps should be destroyed before dm2
149 // objects should be destroyed after dm2
150 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
151 auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
152 // CHECK: call void @_ZN10destroyme1D1Ev
153 destroyme2 dm2;
154 // CHECK: call void @_ZN10destroyme2D1Ev
155 // CHECK: call void @_ZN8witharg1D1Ev
156}
Sebastian Redlbac5cf42012-02-19 12:27:56 +0000157
158void fn6() {
159 // CHECK: define void @_Z3fn6v
160 void target(const wantslist1&);
161 // objects should be destroyed before dm2, after call returns
162 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
163 // CHECK: call void @_Z6targetRK10wantslist1
164 target({ destroyme1(), destroyme1() });
165 // CHECK: call void @_ZN10wantslist1D1Ev
166 // CHECK: call void @_ZN10destroyme1D1Ev
167 destroyme2 dm2;
168 // CHECK: call void @_ZN10destroyme2D1Ev
169}
170
171void fn7() {
172 // CHECK: define void @_Z3fn7v
173 // temps should be destroyed before dm2
174 // object should be destroyed after dm2
175 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
176 wantslist1 wl = { destroyme1(), destroyme1() };
177 // CHECK: call void @_ZN10destroyme1D1Ev
178 destroyme2 dm2;
179 // CHECK: call void @_ZN10destroyme2D1Ev
180 // CHECK: call void @_ZN10wantslist1D1Ev
181}
Sebastian Redlaf130fd2012-02-19 12:28:02 +0000182
183void fn8() {
184 // CHECK: define void @_Z3fn8v
185 void target(std::initializer_list<std::initializer_list<destroyme1>>);
186 // objects should be destroyed before dm2, after call returns
187 // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
188 std::initializer_list<destroyme1> inner;
189 target({ inner, { destroyme1() } });
190 // CHECK: call void @_ZN10destroyme1D1Ev
191 // Only one destroy loop, since only one inner init list is directly inited.
192 // CHECK-NOT: call void @_ZN10destroyme1D1Ev
193 destroyme2 dm2;
194 // CHECK: call void @_ZN10destroyme2D1Ev
195}
196
197void fn9() {
198 // CHECK: define void @_Z3fn9v
199 // objects should be destroyed after dm2
200 std::initializer_list<destroyme1> inner;
201 std::initializer_list<std::initializer_list<destroyme1>> list =
202 { inner, { destroyme1() } };
203 destroyme2 dm2;
204 // CHECK: call void @_ZN10destroyme2D1Ev
205 // CHECK: call void @_ZN10destroyme1D1Ev
206 // Only one destroy loop, since only one inner init list is directly inited.
207 // CHECK-NOT: call void @_ZN10destroyme1D1Ev
208 // CHECK: ret void
209}
Sebastian Redl924db712012-02-19 15:41:54 +0000210
211struct haslist1 {
212 std::initializer_list<int> il;
213 haslist1();
214};
215
216// CHECK: define void @_ZN8haslist1C2Ev
217haslist1::haslist1()
218// CHECK: alloca [3 x i32]
219// CHECK: store i32 1
220// CHECK: store i32 2
221// CHECK: store i32 3
222// CHECK: store i{{32|64}} 3
223 : il{1, 2, 3}
224{
225 destroyme2 dm2;
226}
227
228struct haslist2 {
229 std::initializer_list<destroyme1> il;
230 haslist2();
231};
232
233// CHECK: define void @_ZN8haslist2C2Ev
234haslist2::haslist2()
235 : il{destroyme1(), destroyme1()}
236{
237 destroyme2 dm2;
238 // CHECK: call void @_ZN10destroyme2D1Ev
239 // CHECK: call void @_ZN10destroyme1D1Ev
240}
Sebastian Redl972edf02012-02-19 16:03:09 +0000241
242void fn10() {
243 // CHECK: define void @_Z4fn10v
244 // CHECK: alloca [3 x i32]
Benjamin Kramer4b45d7f2012-02-19 16:20:58 +0000245 // CHECK: call noalias i8* @_Znw{{[jm]}}
Sebastian Redl972edf02012-02-19 16:03:09 +0000246 // CHECK: store i32 1
247 // CHECK: store i32 2
248 // CHECK: store i32 3
249 // CHECK: store i32*
250 // CHECK: store i{{32|64}} 3
251 (void) new std::initializer_list<int> {1, 2, 3};
252}
253
254void fn11() {
255 // CHECK: define void @_Z4fn11v
256 (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
257 // CHECK: call void @_ZN10destroyme1D1Ev
258 destroyme2 dm2;
259 // CHECK: call void @_ZN10destroyme2D1Ev
260}
Sebastian Redl28357452012-03-05 19:35:43 +0000261
262namespace PR12178 {
263 struct string {
264 string(int);
265 ~string();
266 };
267
268 struct pair {
269 string a;
270 int b;
271 };
272
273 struct map {
274 map(std::initializer_list<pair>);
275 };
276
277 map m{ {1, 2}, {3, 4} };
278}
Douglas Gregor29a11f42013-04-06 00:46:20 +0000279
280namespace rdar13325066 {
281 struct X { ~X(); };
282
283 // CHECK: define void @_ZN12rdar133250664loopERNS_1XES1_
284 void loop(X &x1, X &x2) {
285 // CHECK: br label
286 // CHECK: br i1
287 // CHECK: br label
288 // CHECK call void @_ZN12rdar133250661XD1Ev
289 // CHECK: br label
290 // CHECK: br label
291 // CHECK: call void @_ZN12rdar133250661XD1Ev
292 // CHECK: br i1
293 // CHECK: br label
294 // CHECK: ret void
295 for (X x : { x1, x2 }) { }
296 }
297}
Richard Smithe69fb202013-05-23 21:54:14 +0000298
299namespace dtors {
300 struct S {
301 S();
302 ~S();
303 };
Richard Smith7c3e6152013-06-12 22:31:48 +0000304 void z();
305
306 // CHECK: define void @_ZN5dtors1fEv(
Richard Smithe69fb202013-05-23 21:54:14 +0000307 void f() {
Richard Smith7b7db262013-06-13 18:07:12 +0000308 // CHECK: call void @_ZN5dtors1SC1Ev(
309 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smithe69fb202013-05-23 21:54:14 +0000310 std::initializer_list<S>{ S(), S() };
Richard Smith7c3e6152013-06-12 22:31:48 +0000311
312 // Destruction loop for underlying array.
313 // CHECK: br label
314 // CHECK: call void @_ZN5dtors1SD1Ev(
315 // CHECK: br i1
316
317 // CHECK: call void @_ZN5dtors1zEv(
318 z();
319
320 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
Richard Smithe69fb202013-05-23 21:54:14 +0000321 }
Richard Smith7c3e6152013-06-12 22:31:48 +0000322
323 // CHECK: define void @_ZN5dtors1gEv(
Richard Smith211c8dd2013-06-05 00:46:14 +0000324 void g() {
Richard Smith7b7db262013-06-13 18:07:12 +0000325 // CHECK: call void @_ZN5dtors1SC1Ev(
326 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smith211c8dd2013-06-05 00:46:14 +0000327 auto x = std::initializer_list<S>{ S(), S() };
Richard Smith7c3e6152013-06-12 22:31:48 +0000328
329 // Destruction loop for underlying array.
330 // CHECK: br label
331 // CHECK: call void @_ZN5dtors1SD1Ev(
332 // CHECK: br i1
333
334 // CHECK: call void @_ZN5dtors1zEv(
335 z();
336
337 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
338 }
339
340 // CHECK: define void @_ZN5dtors1hEv(
341 void h() {
Richard Smith7b7db262013-06-13 18:07:12 +0000342 // CHECK: call void @_ZN5dtors1SC1Ev(
343 // CHECK: call void @_ZN5dtors1SC1Ev(
Richard Smith7c3e6152013-06-12 22:31:48 +0000344 std::initializer_list<S> x = { S(), S() };
345
346 // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
347
348 // CHECK: call void @_ZN5dtors1zEv(
349 z();
350
351 // Destruction loop for underlying array.
352 // CHECK: br label
353 // CHECK: call void @_ZN5dtors1SD1Ev(
354 // CHECK: br i1
Richard Smith211c8dd2013-06-05 00:46:14 +0000355 }
Richard Smithe69fb202013-05-23 21:54:14 +0000356}