1 | // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX11 |
2 | // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++17 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX17 |
3 | // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK,NULL-VALID,CHECK-CXX11 |
4 | |
5 | namespace PR16263 { |
6 | const unsigned int n = 1234; |
7 | extern const int &r = (const int&)n; |
8 | // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234, |
9 | // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_, |
10 | |
11 | extern const int &s = reinterpret_cast<const int&>(n); |
12 | // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 4 |
13 | // CHECK: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8 |
14 | |
15 | struct A { int n; }; |
16 | struct B { int n; }; |
17 | struct C : A, B {}; |
18 | extern const A &&a = (A&&)(A&&)(C&&)(C{}); |
19 | // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer, |
20 | // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to |
21 | |
22 | extern const int &&t = ((B&&)C{}).n; |
23 | // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer, |
24 | // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4 |
25 | |
26 | struct D { double d; C c; }; |
27 | extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n); |
28 | // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer |
29 | // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12 |
30 | } |
31 | |
32 | namespace PR20227 { |
33 | struct A { ~A(); }; |
34 | struct B { virtual ~B(); }; |
35 | struct C : B {}; |
36 | |
37 | A &&a = dynamic_cast<A&&>(A{}); |
38 | // CHECK: @_ZGRN7PR202271aE_ = internal global |
39 | |
40 | B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{})); |
41 | // CHECK: @_ZGRN7PR202271bE_ = internal global |
42 | |
43 | B &&c = static_cast<C&&>(static_cast<B&&>(C{})); |
44 | // CHECK: @_ZGRN7PR202271cE_ = internal global |
45 | } |
46 | |
47 | namespace BraceInit { |
48 | typedef const int &CIR; |
49 | CIR x = CIR{3}; |
50 | // CHECK-CXX11: @_ZGRN9BraceInit1xE_ = internal constant i32 3 |
51 | // FIXME: This should still be emitted as 'constant' in C++17. |
52 | // CHECK-CXX17: @_ZGRN9BraceInit1xE_ = internal global i32 3 |
53 | // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_ |
54 | } |
55 | |
56 | struct A { |
57 | A(); |
58 | ~A(); |
59 | void f(); |
60 | }; |
61 | |
62 | void f1() { |
63 | // CHECK: call void @_ZN1AC1Ev |
64 | // CHECK: call void @_ZN1AD1Ev |
65 | (void)A(); |
66 | |
67 | // CHECK: call void @_ZN1AC1Ev |
68 | // CHECK: call void @_ZN1AD1Ev |
69 | A().f(); |
70 | } |
71 | |
72 | // Function calls |
73 | struct B { |
74 | B(); |
75 | ~B(); |
76 | }; |
77 | |
78 | B g(); |
79 | |
80 | void f2() { |
81 | // CHECK-NOT: call void @_ZN1BC1Ev |
82 | // CHECK: call void @_ZN1BD1Ev |
83 | (void)g(); |
84 | } |
85 | |
86 | // Member function calls |
87 | struct C { |
88 | C(); |
89 | ~C(); |
90 | |
91 | C f(); |
92 | }; |
93 | |
94 | void f3() { |
95 | // CHECK: call void @_ZN1CC1Ev |
96 | // CHECK: call void @_ZN1CD1Ev |
97 | // CHECK: call void @_ZN1CD1Ev |
98 | C().f(); |
99 | } |
100 | |
101 | // Function call operator |
102 | struct D { |
103 | D(); |
104 | ~D(); |
105 | |
106 | D operator()(); |
107 | }; |
108 | |
109 | void f4() { |
110 | // CHECK: call void @_ZN1DC1Ev |
111 | // CHECK: call void @_ZN1DD1Ev |
112 | // CHECK: call void @_ZN1DD1Ev |
113 | D()(); |
114 | } |
115 | |
116 | // Overloaded operators |
117 | struct E { |
118 | E(); |
119 | ~E(); |
120 | E operator+(const E&); |
121 | E operator!(); |
122 | }; |
123 | |
124 | void f5() { |
125 | // CHECK: call void @_ZN1EC1Ev |
126 | // CHECK: call void @_ZN1EC1Ev |
127 | // CHECK: call void @_ZN1ED1Ev |
128 | // CHECK: call void @_ZN1ED1Ev |
129 | // CHECK: call void @_ZN1ED1Ev |
130 | E() + E(); |
131 | |
132 | // CHECK: call void @_ZN1EC1Ev |
133 | // CHECK: call void @_ZN1ED1Ev |
134 | // CHECK: call void @_ZN1ED1Ev |
135 | !E(); |
136 | } |
137 | |
138 | struct F { |
139 | F(); |
140 | ~F(); |
141 | F& f(); |
142 | }; |
143 | |
144 | void f6() { |
145 | // CHECK: call void @_ZN1FC1Ev |
146 | // CHECK: call void @_ZN1FD1Ev |
147 | F().f(); |
148 | } |
149 | |
150 | struct G { |
151 | G(); |
152 | G(A); |
153 | ~G(); |
154 | operator A(); |
155 | }; |
156 | |
157 | void a(const A&); |
158 | |
159 | void f7() { |
160 | // CHECK: call void @_ZN1AC1Ev |
161 | // CHECK: call void @_Z1aRK1A |
162 | // CHECK: call void @_ZN1AD1Ev |
163 | a(A()); |
164 | |
165 | // CHECK: call void @_ZN1GC1Ev |
166 | // CHECK: call void @_ZN1Gcv1AEv |
167 | // CHECK: call void @_Z1aRK1A |
168 | // CHECK: call void @_ZN1AD1Ev |
169 | // CHECK: call void @_ZN1GD1Ev |
170 | a(G()); |
171 | } |
172 | |
173 | namespace PR5077 { |
174 | |
175 | struct A { |
176 | A(); |
177 | ~A(); |
178 | int f(); |
179 | }; |
180 | |
181 | void f(); |
182 | int g(const A&); |
183 | |
184 | struct B { |
185 | int a1; |
186 | int a2; |
187 | B(); |
188 | ~B(); |
189 | }; |
190 | |
191 | B::B() |
192 | // CHECK: call void @_ZN6PR50771AC1Ev |
193 | // CHECK: call i32 @_ZN6PR50771A1fEv |
194 | // CHECK: call void @_ZN6PR50771AD1Ev |
195 | : a1(A().f()) |
196 | // CHECK: call void @_ZN6PR50771AC1Ev |
197 | // CHECK: call i32 @_ZN6PR50771gERKNS_1AE |
198 | // CHECK: call void @_ZN6PR50771AD1Ev |
199 | , a2(g(A())) |
200 | { |
201 | // CHECK: call void @_ZN6PR50771fEv |
202 | f(); |
203 | } |
204 | |
205 | } |
206 | |
207 | A f8() { |
208 | // CHECK: call void @_ZN1AC1Ev |
209 | // CHECK-NOT: call void @_ZN1AD1Ev |
210 | return A(); |
211 | // CHECK: ret void |
212 | } |
213 | |
214 | struct H { |
215 | H(); |
216 | ~H(); |
217 | H(const H&); |
218 | }; |
219 | |
220 | void f9(H h) { |
221 | // CHECK: call void @_ZN1HC1Ev |
222 | // CHECK: call void @_Z2f91H |
223 | // CHECK: call void @_ZN1HD1Ev |
224 | f9(H()); |
225 | |
226 | // CHECK: call void @_ZN1HC1ERKS_ |
227 | // CHECK: call void @_Z2f91H |
228 | // CHECK: call void @_ZN1HD1Ev |
229 | f9(h); |
230 | } |
231 | |
232 | void f10(const H&); |
233 | |
234 | void f11(H h) { |
235 | // CHECK: call void @_ZN1HC1Ev |
236 | // CHECK: call void @_Z3f10RK1H |
237 | // CHECK: call void @_ZN1HD1Ev |
238 | f10(H()); |
239 | |
240 | // CHECK: call void @_Z3f10RK1H |
241 | // CHECK-NOT: call void @_ZN1HD1Ev |
242 | // CHECK: ret void |
243 | f10(h); |
244 | } |
245 | |
246 | // PR5808 |
247 | struct I { |
248 | I(const char *); |
249 | ~I(); |
250 | }; |
251 | |
252 | // CHECK: _Z3f12v |
253 | I f12() { |
254 | // CHECK: call void @_ZN1IC1EPKc |
255 | // CHECK-NOT: call void @_ZN1ID1Ev |
256 | // CHECK: ret void |
257 | return "Hello"; |
258 | } |
259 | |
260 | // PR5867 |
261 | namespace PR5867 { |
262 | struct S { |
263 | S(); |
264 | S(const S &); |
265 | ~S(); |
266 | }; |
267 | |
268 | void f(S, int); |
269 | // CHECK-LABEL: define void @_ZN6PR58671gEv |
270 | void g() { |
271 | // CHECK: call void @_ZN6PR58671SC1Ev |
272 | // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi |
273 | // CHECK-NEXT: call void @_ZN6PR58671SD1Ev |
274 | // CHECK-NEXT: ret void |
275 | (f)(S(), 0); |
276 | } |
277 | |
278 | // CHECK-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_ |
279 | template<typename T> |
280 | void g2(T) { |
281 | // CHECK: call void @_ZN6PR58671SC1Ev |
282 | // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi |
283 | // CHECK-NEXT: call void @_ZN6PR58671SD1Ev |
284 | // CHECK-NEXT: ret void |
285 | (f)(S(), 0); |
286 | } |
287 | |
288 | void h() { |
289 | g2(17); |
290 | } |
291 | } |
292 | |
293 | // PR6199 |
294 | namespace PR6199 { |
295 | struct A { ~A(); }; |
296 | |
297 | struct B { operator A(); }; |
298 | |
299 | // CHECK-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_ |
300 | template<typename T> A f2(T) { |
301 | B b; |
302 | // CHECK: call void @_ZN6PR61991BcvNS_1AEEv |
303 | // CHECK-NEXT: ret void |
304 | return b; |
305 | } |
306 | |
307 | template A f2<int>(int); |
308 | |
309 | } |
310 | |
311 | namespace T12 { |
312 | |
313 | struct A { |
314 | A(); |
315 | ~A(); |
316 | int f(); |
317 | }; |
318 | |
319 | int& f(int); |
320 | |
321 | // CHECK-LABEL: define void @_ZN3T121gEv |
322 | void g() { |
323 | // CHECK: call void @_ZN3T121AC1Ev |
324 | // CHECK-NEXT: call i32 @_ZN3T121A1fEv( |
325 | // CHECK-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi( |
326 | // CHECK-NEXT: call void @_ZN3T121AD1Ev( |
327 | int& i = f(A().f()); |
328 | } |
329 | |
330 | } |
331 | |
332 | namespace PR6648 { |
333 | struct B { |
334 | ~B(); |
335 | }; |
336 | B foo; |
337 | struct D; |
338 | D& zed(B); |
339 | void foobar() { |
340 | // NULL-INVALID: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE |
341 | // NULL-VALID: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE |
342 | zed(foo); |
343 | } |
344 | } |
345 | |
346 | namespace UserConvertToValue { |
347 | struct X { |
348 | X(int); |
349 | X(const X&); |
350 | ~X(); |
351 | }; |
352 | |
353 | void f(X); |
354 | |
355 | // CHECK: void @_ZN18UserConvertToValue1gEv() |
356 | void g() { |
357 | // CHECK: call void @_ZN18UserConvertToValue1XC1Ei |
358 | // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE |
359 | // CHECK: call void @_ZN18UserConvertToValue1XD1Ev |
360 | // CHECK: ret void |
361 | f(1); |
362 | } |
363 | } |
364 | |
365 | namespace PR7556 { |
366 | struct A { ~A(); }; |
367 | struct B { int i; ~B(); }; |
368 | struct C { int C::*pm; ~C(); }; |
369 | // CHECK-LABEL: define void @_ZN6PR75563fooEv() |
370 | void foo() { |
371 | // CHECK: call void @_ZN6PR75561AD1Ev |
372 | A(); |
373 | // CHECK: call void @llvm.memset.p0i8.i64 |
374 | // CHECK: call void @_ZN6PR75561BD1Ev |
375 | B(); |
376 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 |
377 | // CHECK: call void @_ZN6PR75561CD1Ev |
378 | C(); |
379 | // CHECK-NEXT: ret void |
380 | } |
381 | } |
382 | |
383 | namespace Elision { |
384 | struct A { |
385 | A(); A(const A &); ~A(); |
386 | void *p; |
387 | void foo() const; |
388 | }; |
389 | |
390 | void foo(); |
391 | A fooA(); |
392 | void takeA(A a); |
393 | |
394 | // CHECK-LABEL: define void @_ZN7Elision5test0Ev() |
395 | void test0() { |
396 | // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8 |
397 | // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 |
398 | // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8 |
399 | // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8 |
400 | // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8 |
401 | |
402 | // CHECK-NEXT: call void @_ZN7Elision3fooEv() |
403 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) |
404 | A i = (foo(), A()); |
405 | |
406 | // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]]) |
407 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) |
408 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) |
409 | A j = (fooA(), A()); |
410 | |
411 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]]) |
412 | // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]]) |
413 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]]) |
414 | A k = (A(), fooA()); |
415 | |
416 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]]) |
417 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) |
418 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) |
419 | } |
420 | |
421 | |
422 | // CHECK-LABEL: define void @_ZN7Elision5test1EbNS_1AE( |
423 | void test1(bool c, A x) { |
424 | // CHECK: [[I:%.*]] = alloca [[A]], align 8 |
425 | // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 |
426 | |
427 | // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) |
428 | // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) |
429 | A i = (c ? A() : x); |
430 | |
431 | // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) |
432 | // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) |
433 | A j = (c ? x : A()); |
434 | |
435 | // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) |
436 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) |
437 | } |
438 | |
439 | // CHECK: define void @_ZN7Elision5test2Ev([[A]]* noalias sret |
440 | A test2() { |
441 | // CHECK: call void @_ZN7Elision3fooEv() |
442 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) |
443 | // CHECK-NEXT: ret void |
444 | return (foo(), A()); |
445 | } |
446 | |
447 | // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret |
448 | A test3(int v, A x) { |
449 | if (v < 5) |
450 | // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) |
451 | // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) |
452 | return (v < 0 ? A() : x); |
453 | else |
454 | // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) |
455 | // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]]) |
456 | return (v > 10 ? x : A()); |
457 | |
458 | // CHECK: ret void |
459 | } |
460 | |
461 | // CHECK-LABEL: define void @_ZN7Elision5test4Ev() |
462 | void test4() { |
463 | // CHECK: [[X:%.*]] = alloca [[A]], align 8 |
464 | // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16 |
465 | |
466 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]]) |
467 | A x; |
468 | |
469 | // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0 |
470 | // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]]) |
471 | // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1 |
472 | // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) |
473 | A xs[] = { A(), x }; |
474 | |
475 | // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0 |
476 | // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2 |
477 | // CHECK-NEXT: br label |
478 | // CHECK: [[AFTER:%.*]] = phi [[A]]* |
479 | // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 |
480 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]]) |
481 | // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] |
482 | // CHECK-NEXT: br i1 [[T0]], |
483 | |
484 | // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) |
485 | } |
486 | |
487 | // rdar://problem/8433352 |
488 | // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias sret |
489 | struct B { A a; B(); }; |
490 | A test5() { |
491 | // CHECK: [[AT0:%.*]] = alloca [[A]], align 8 |
492 | // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8 |
493 | // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8 |
494 | // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8 |
495 | // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8 |
496 | |
497 | // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]]) |
498 | // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0 |
499 | // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) |
500 | // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]]) |
501 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]]) |
502 | // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]]) |
503 | takeA(B().a); |
504 | |
505 | // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]]) |
506 | // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0 |
507 | // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) |
508 | // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]]) |
509 | A x = B().a; |
510 | |
511 | // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]]) |
512 | // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0 |
513 | // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) |
514 | // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]]) |
515 | return B().a; |
516 | |
517 | // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) |
518 | } |
519 | |
520 | // Reduced from webkit. |
521 | // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]* |
522 | struct C { operator A() const; }; |
523 | void test6(const C *x) { |
524 | // CHECK: [[T0:%.*]] = alloca [[A]], align 8 |
525 | // CHECK: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8 |
526 | // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]]) |
527 | // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]]) |
528 | // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) |
529 | // CHECK-NEXT: ret void |
530 | A(*x).foo(); |
531 | } |
532 | } |
533 | |
534 | namespace PR8623 { |
535 | struct A { A(int); ~A(); }; |
536 | |
537 | // CHECK-LABEL: define void @_ZN6PR86233fooEb( |
538 | void foo(bool b) { |
539 | // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 |
540 | // CHECK-NEXT: [[LCONS:%.*]] = alloca i1 |
541 | // CHECK-NEXT: [[RCONS:%.*]] = alloca i1 |
542 | // CHECK: store i1 false, i1* [[LCONS]] |
543 | // CHECK-NEXT: store i1 false, i1* [[RCONS]] |
544 | // CHECK-NEXT: br i1 |
545 | // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2) |
546 | // CHECK-NEXT: store i1 true, i1* [[LCONS]] |
547 | // CHECK-NEXT: br label |
548 | // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3) |
549 | // CHECK-NEXT: store i1 true, i1* [[RCONS]] |
550 | // CHECK-NEXT: br label |
551 | // CHECK: load i1, i1* [[RCONS]] |
552 | // CHECK-NEXT: br i1 |
553 | // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) |
554 | // CHECK-NEXT: br label |
555 | // CHECK: load i1, i1* [[LCONS]] |
556 | // CHECK-NEXT: br i1 |
557 | // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) |
558 | // CHECK-NEXT: br label |
559 | // CHECK: ret void |
560 | b ? A(2) : A(3); |
561 | } |
562 | } |
563 | |
564 | namespace PR11365 { |
565 | struct A { A(); ~A(); }; |
566 | |
567 | // CHECK-LABEL: define void @_ZN7PR113653fooEv( |
568 | void foo() { |
569 | // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 |
570 | // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3 |
571 | // CHECK-NEXT: br label |
572 | |
573 | // CHECK: [[PHI:%.*]] = phi |
574 | // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1 |
575 | // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]]) |
576 | // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]] |
577 | // CHECK-NEXT: br i1 |
578 | (void) (A [3]) {}; |
579 | } |
580 | } |
581 | |
582 | namespace AssignmentOp { |
583 | struct A { ~A(); }; |
584 | struct B { A operator=(const B&); }; |
585 | struct C : B { B b1, b2; }; |
586 | // CHECK-LABEL: define void @_ZN12AssignmentOp1fE |
587 | void f(C &c1, const C &c2) { |
588 | // CHECK: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_( |
589 | c1 = c2; |
590 | } |
591 | |
592 | // Ensure that each 'A' temporary is destroyed before the next subobject is |
593 | // copied. |
594 | // CHECK: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_( |
595 | // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS |
596 | // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( |
597 | // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS |
598 | // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( |
599 | // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS |
600 | // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( |
601 | } |
602 | |
603 | namespace BindToSubobject { |
604 | struct A { |
605 | A(); |
606 | ~A(); |
607 | int a; |
608 | }; |
609 | |
610 | void f(), g(); |
611 | |
612 | // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_) |
613 | // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle) |
614 | // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8 |
615 | int &&a = A().a; |
616 | |
617 | // CHECK: call void @_ZN15BindToSubobject1fEv() |
618 | // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_) |
619 | // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle) |
620 | // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8 |
621 | int &&b = (f(), A().a); |
622 | |
623 | int A::*h(); |
624 | |
625 | // CHECK: call void @_ZN15BindToSubobject1fEv() |
626 | // CHECK: call void @_ZN15BindToSubobject1gEv() |
627 | // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_) |
628 | // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle) |
629 | // CHECK: call {{.*}} @_ZN15BindToSubobject1hE |
630 | // CHECK: getelementptr |
631 | // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8 |
632 | int &&c = (f(), (g(), A().*h())); |
633 | |
634 | struct B { |
635 | int padding; |
636 | A a; |
637 | }; |
638 | |
639 | // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_) |
640 | // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle) |
641 | // CHECK: call {{.*}} @_ZN15BindToSubobject1hE |
642 | // CHECK: getelementptr {{.*}} getelementptr |
643 | // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8 |
644 | int &&d = (B().a).*h(); |
645 | } |
646 | |
647 | namespace Bitfield { |
648 | struct S { int a : 5; ~S(); }; |
649 | |
650 | // Do not lifetime extend the S() temporary here. |
651 | // CHECK: alloca |
652 | // CHECK: call {{.*}}memset |
653 | // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_ |
654 | // CHECK: call void @_ZN8Bitfield1SD1 |
655 | // CHECK: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8 |
656 | int &&r = S().a; |
657 | } |
658 | |
659 | namespace Vector { |
660 | typedef __attribute__((vector_size(16))) int vi4a; |
661 | typedef __attribute__((ext_vector_type(4))) int vi4b; |
662 | struct S { |
663 | vi4a v; |
664 | vi4b w; |
665 | }; |
666 | // CHECK: alloca |
667 | // CHECK: extractelement |
668 | // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_ |
669 | // CHECK: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE, |
670 | int &&r = S().v[1]; |
671 | |
672 | // CHECK: alloca |
673 | // CHECK: extractelement |
674 | // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_ |
675 | // CHECK: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE, |
676 | int &&s = S().w[1]; |
677 | // FIXME PR16204: The following code leads to an assertion in Sema. |
678 | //int &&s = S().w.y; |
679 | } |
680 | |
681 | namespace ImplicitTemporaryCleanup { |
682 | struct A { A(int); ~A(); }; |
683 | void g(); |
684 | |
685 | // CHECK-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv( |
686 | void f() { |
687 | // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei( |
688 | A &&a = 0; |
689 | |
690 | // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv( |
691 | g(); |
692 | |
693 | // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev( |
694 | } |
695 | } |
696 | |
697 | namespace MultipleExtension { |
698 | struct A { A(); ~A(); }; |
699 | struct B { B(); ~B(); }; |
700 | struct C { C(); ~C(); }; |
701 | struct D { D(); ~D(); int n; C c; }; |
702 | struct E { const A &a; B b; const C &c; ~E(); }; |
703 | |
704 | E &&e1 = { A(), B(), D().c }; |
705 | |
706 | // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]]) |
707 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] |
708 | // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0) |
709 | |
710 | // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1)) |
711 | |
712 | // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]]) |
713 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] |
714 | // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2) |
715 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]] |
716 | // CHECK: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8 |
717 | |
718 | E e2 = { A(), B(), D().c }; |
719 | |
720 | // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]]) |
721 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] |
722 | // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0) |
723 | |
724 | // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1)) |
725 | |
726 | // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]]) |
727 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] |
728 | // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2) |
729 | // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]] |
730 | |
731 | |
732 | void g(); |
733 | // CHECK: define void @[[NS:_ZN17MultipleExtension]]1fEv( |
734 | void f() { |
735 | E &&e1 = { A(), B(), D().c }; |
736 | // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0 |
737 | // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]]) |
738 | // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]] |
739 | // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1 |
740 | // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]]) |
741 | // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2 |
742 | // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]]) |
743 | // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1 |
744 | // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]] |
745 | // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]] |
746 | |
747 | g(); |
748 | // CHECK: call void @[[NS]]1gEv() |
749 | |
750 | E e2 = { A(), B(), D().c }; |
751 | // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0 |
752 | // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]]) |
753 | // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]] |
754 | // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1 |
755 | // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]]) |
756 | // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2 |
757 | // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]]) |
758 | // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1 |
759 | // CHECK: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]] |
760 | |
761 | g(); |
762 | // CHECK: call void @[[NS]]1gEv() |
763 | |
764 | // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]]) |
765 | // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]]) |
766 | // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]]) |
767 | // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]]) |
768 | // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]]) |
769 | // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]]) |
770 | } |
771 | } |
772 | |
773 | namespace ArrayAccess { |
774 | struct A { A(int); ~A(); }; |
775 | void g(); |
776 | void f() { |
777 | using T = A[3]; |
778 | |
779 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1 |
780 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
781 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2 |
782 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
783 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3 |
784 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
785 | A &&a = T{1, 2, 3}[1]; |
786 | |
787 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4 |
788 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
789 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5 |
790 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
791 | // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6 |
792 | // CHECK-NOT: @_ZN11ArrayAccess1AD |
793 | A &&b = 2[T{4, 5, 6}]; |
794 | |
795 | // CHECK: call void @_ZN11ArrayAccess1gEv( |
796 | g(); |
797 | |
798 | // CHECK: call void @_ZN11ArrayAccess1AD |
799 | // CHECK: call void @_ZN11ArrayAccess1AD |
800 | } |
801 | } |
802 | |
803 | namespace PR14130 { |
804 | struct S { S(int); }; |
805 | struct U { S &&s; }; |
806 | U v { { 0 } }; |
807 | // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0) |
808 | // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE |
809 | } |
810 | |
811 | namespace Conditional { |
812 | struct A {}; |
813 | struct B : A { B(); ~B(); }; |
814 | struct C : A { C(); ~C(); }; |
815 | |
816 | void g(); |
817 | |
818 | // CHECK-LABEL: define {{.*}} @_ZN11Conditional1fEb( |
819 | void f(bool b) { |
820 | // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]], |
821 | // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]], |
822 | // CHECK: br i1 |
823 | // |
824 | // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev( |
825 | // CHECK: store i1 true, i1* %[[CLEANUP_B]], |
826 | // CHECK: br label |
827 | // |
828 | // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev( |
829 | // CHECK: store i1 true, i1* %[[CLEANUP_C]], |
830 | // CHECK: br label |
831 | A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C()); |
832 | |
833 | // CHECK: call {{.*}} @_ZN11Conditional1gEv( |
834 | g(); |
835 | |
836 | // CHECK: load {{.*}} %[[CLEANUP_C]] |
837 | // CHECK: br i1 |
838 | // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev( |
839 | // CHECK: br label |
840 | |
841 | // CHECK: load {{.*}} %[[CLEANUP_B]] |
842 | // CHECK: br i1 |
843 | // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev( |
844 | // CHECK: br label |
845 | } |
846 | |
847 | struct D { A &&a; }; |
848 | // CHECK-LABEL: define {{.*}} @_ZN11Conditional10f_indirectEb( |
849 | void f_indirect(bool b) { |
850 | // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]], |
851 | // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]], |
852 | // CHECK: br i1 |
853 | // |
854 | // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev( |
855 | // CHECK: store i1 true, i1* %[[CLEANUP_B]], |
856 | // CHECK: br label |
857 | // |
858 | // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev( |
859 | // CHECK: store i1 true, i1* %[[CLEANUP_C]], |
860 | // CHECK: br label |
861 | D d = b ? D{B()} : D{C()}; |
862 | |
863 | // In C++17, the expression D{...} directly initializes the 'd' object, so |
864 | // lifetime-extending the temporaries to the lifetime of the D object |
865 | // extends them past the call to g(). |
866 | // |
867 | // In C++14 and before, D is move-constructed from the result of the |
868 | // conditional expression, so no lifetime extension occurs. |
869 | |
870 | // CHECK-CXX17: call {{.*}} @_ZN11Conditional1gEv( |
871 | |
872 | // CHECK: load {{.*}} %[[CLEANUP_C]] |
873 | // CHECK: br i1 |
874 | // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev( |
875 | // CHECK: br label |
876 | |
877 | // CHECK: load {{.*}} %[[CLEANUP_B]] |
878 | // CHECK: br i1 |
879 | // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev( |
880 | // CHECK: br label |
881 | |
882 | // CHECK-CXX11: call {{.*}} @_ZN11Conditional1gEv( |
883 | g(); |
884 | } |
885 | |
886 | extern bool b; |
887 | // CHECK: load {{.*}} @_ZN11Conditional1b |
888 | // CHECK: br i1 |
889 | // |
890 | // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev({{.*}} @_ZGRN11Conditional1rE_) |
891 | // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1BD1Ev {{.*}} @_ZGRN11Conditional1rE_, |
892 | // CHECK: br label |
893 | // |
894 | // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev({{.*}} @_ZGRN11Conditional1rE0_) |
895 | // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1CD1Ev {{.*}} @_ZGRN11Conditional1rE0_, |
896 | // CHECK: br label |
897 | A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C()); |
898 | } |
899 | |