1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2 struct A {
3 A();
4 ~A();
5 void f();
6 };
7
f1()8 void f1() {
9 // CHECK: call void @_ZN1AC1Ev
10 // CHECK: call void @_ZN1AD1Ev
11 (void)A();
12
13 // CHECK: call void @_ZN1AC1Ev
14 // CHECK: call void @_ZN1AD1Ev
15 A().f();
16 }
17
18 // Function calls
19 struct B {
20 B();
21 ~B();
22 };
23
24 B g();
25
f2()26 void f2() {
27 // CHECK-NOT: call void @_ZN1BC1Ev
28 // CHECK: call void @_ZN1BD1Ev
29 (void)g();
30 }
31
32 // Member function calls
33 struct C {
34 C();
35 ~C();
36
37 C f();
38 };
39
f3()40 void f3() {
41 // CHECK: call void @_ZN1CC1Ev
42 // CHECK: call void @_ZN1CD1Ev
43 // CHECK: call void @_ZN1CD1Ev
44 C().f();
45 }
46
47 // Function call operator
48 struct D {
49 D();
50 ~D();
51
52 D operator()();
53 };
54
f4()55 void f4() {
56 // CHECK: call void @_ZN1DC1Ev
57 // CHECK: call void @_ZN1DD1Ev
58 // CHECK: call void @_ZN1DD1Ev
59 D()();
60 }
61
62 // Overloaded operators
63 struct E {
64 E();
65 ~E();
66 E operator+(const E&);
67 E operator!();
68 };
69
f5()70 void f5() {
71 // CHECK: call void @_ZN1EC1Ev
72 // CHECK: call void @_ZN1EC1Ev
73 // CHECK: call void @_ZN1ED1Ev
74 // CHECK: call void @_ZN1ED1Ev
75 // CHECK: call void @_ZN1ED1Ev
76 E() + E();
77
78 // CHECK: call void @_ZN1EC1Ev
79 // CHECK: call void @_ZN1ED1Ev
80 // CHECK: call void @_ZN1ED1Ev
81 !E();
82 }
83
84 struct F {
85 F();
86 ~F();
87 F& f();
88 };
89
f6()90 void f6() {
91 // CHECK: call void @_ZN1FC1Ev
92 // CHECK: call void @_ZN1FD1Ev
93 F().f();
94 }
95
96 struct G {
97 G();
98 G(A);
99 ~G();
100 operator A();
101 };
102
103 void a(const A&);
104
f7()105 void f7() {
106 // CHECK: call void @_ZN1AC1Ev
107 // CHECK: call void @_Z1aRK1A
108 // CHECK: call void @_ZN1AD1Ev
109 a(A());
110
111 // CHECK: call void @_ZN1GC1Ev
112 // CHECK: call void @_ZN1Gcv1AEv
113 // CHECK: call void @_Z1aRK1A
114 // CHECK: call void @_ZN1AD1Ev
115 // CHECK: call void @_ZN1GD1Ev
116 a(G());
117 }
118
119 namespace PR5077 {
120
121 struct A {
122 A();
123 ~A();
124 int f();
125 };
126
127 void f();
128 int g(const A&);
129
130 struct B {
131 int a1;
132 int a2;
133 B();
134 ~B();
135 };
136
B()137 B::B()
138 // CHECK: call void @_ZN6PR50771AC1Ev
139 // CHECK: call i32 @_ZN6PR50771A1fEv
140 // CHECK: call void @_ZN6PR50771AD1Ev
141 : a1(A().f())
142 // CHECK: call void @_ZN6PR50771AC1Ev
143 // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
144 // CHECK: call void @_ZN6PR50771AD1Ev
145 , a2(g(A()))
146 {
147 // CHECK: call void @_ZN6PR50771fEv
148 f();
149 }
150
151 struct C {
152 C();
153
154 const B& b;
155 };
156
C()157 C::C()
158 // CHECK: call void @_ZN6PR50771BC1Ev
159 : b(B()) {
160 // CHECK: call void @_ZN6PR50771fEv
161 f();
162
163 // CHECK: call void @_ZN6PR50771BD1Ev
164 }
165 }
166
f8()167 A f8() {
168 // CHECK: call void @_ZN1AC1Ev
169 // CHECK-NOT: call void @_ZN1AD1Ev
170 return A();
171 // CHECK: ret void
172 }
173
174 struct H {
175 H();
176 ~H();
177 H(const H&);
178 };
179
f9(H h)180 void f9(H h) {
181 // CHECK: call void @_ZN1HC1Ev
182 // CHECK: call void @_Z2f91H
183 // CHECK: call void @_ZN1HD1Ev
184 f9(H());
185
186 // CHECK: call void @_ZN1HC1ERKS_
187 // CHECK: call void @_Z2f91H
188 // CHECK: call void @_ZN1HD1Ev
189 f9(h);
190 }
191
192 void f10(const H&);
193
f11(H h)194 void f11(H h) {
195 // CHECK: call void @_ZN1HC1Ev
196 // CHECK: call void @_Z3f10RK1H
197 // CHECK: call void @_ZN1HD1Ev
198 f10(H());
199
200 // CHECK: call void @_Z3f10RK1H
201 // CHECK-NOT: call void @_ZN1HD1Ev
202 // CHECK: ret void
203 f10(h);
204 }
205
206 // PR5808
207 struct I {
208 I(const char *);
209 ~I();
210 };
211
212 // CHECK: _Z3f12v
f12()213 I f12() {
214 // CHECK: call void @_ZN1IC1EPKc
215 // CHECK-NOT: call void @_ZN1ID1Ev
216 // CHECK: ret void
217 return "Hello";
218 }
219
220 // PR5867
221 namespace PR5867 {
222 struct S {
223 S();
224 S(const S &);
225 ~S();
226 };
227
228 void f(S, int);
229 // CHECK: define void @_ZN6PR58671gEv
g()230 void g() {
231 // CHECK: call void @_ZN6PR58671SC1Ev
232 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
233 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
234 // CHECK-NEXT: ret void
235 (f)(S(), 0);
236 }
237
238 // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
239 template<typename T>
g2(T)240 void g2(T) {
241 // CHECK: call void @_ZN6PR58671SC1Ev
242 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
243 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
244 // CHECK-NEXT: ret void
245 (f)(S(), 0);
246 }
247
h()248 void h() {
249 g2(17);
250 }
251 }
252
253 // PR6199
254 namespace PR6199 {
255 struct A { ~A(); };
256
257 struct B { operator A(); };
258
259 // CHECK: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
f2(T)260 template<typename T> A f2(T) {
261 B b;
262 // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
263 // CHECK-NEXT: ret void
264 return b;
265 }
266
267 template A f2<int>(int);
268
269 }
270
271 namespace T12 {
272
273 struct A {
274 A();
275 ~A();
276 int f();
277 };
278
279 int& f(int);
280
281 // CHECK: define void @_ZN3T121gEv
g()282 void g() {
283 // CHECK: call void @_ZN3T121AC1Ev
284 // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
285 // CHECK-NEXT: call i32* @_ZN3T121fEi(
286 // CHECK-NEXT: call void @_ZN3T121AD1Ev(
287 int& i = f(A().f());
288 }
289
290 }
291
292 namespace PR6648 {
293 struct B {
294 ~B();
295 };
296 B foo;
297 struct D;
298 D& zed(B);
foobar()299 void foobar() {
300 // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
301 zed(foo);
302 }
303 }
304
305 namespace UserConvertToValue {
306 struct X {
307 X(int);
308 X(const X&);
309 ~X();
310 };
311
312 void f(X);
313
314 // CHECK: void @_ZN18UserConvertToValue1gEv()
g()315 void g() {
316 // CHECK: call void @_ZN18UserConvertToValue1XC1Ei
317 // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE
318 // CHECK: call void @_ZN18UserConvertToValue1XD1Ev
319 // CHECK: ret void
320 f(1);
321 }
322 }
323
324 namespace PR7556 {
325 struct A { ~A(); };
326 struct B { int i; ~B(); };
327 struct C { int C::*pm; ~C(); };
328 // CHECK: define void @_ZN6PR75563fooEv()
foo()329 void foo() {
330 // CHECK: call void @_ZN6PR75561AD1Ev
331 A();
332 // CHECK: call void @llvm.memset.p0i8.i64
333 // CHECK: call void @_ZN6PR75561BD1Ev
334 B();
335 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
336 // CHECK: call void @_ZN6PR75561CD1Ev
337 C();
338 // CHECK-NEXT: ret void
339 }
340 }
341
342 namespace Elision {
343 struct A {
344 A(); A(const A &); ~A();
345 void *p;
346 void foo() const;
347 };
348
349 void foo();
350 A fooA();
351 void takeA(A a);
352
353 // CHECK: define void @_ZN7Elision5test0Ev()
test0()354 void test0() {
355 // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8
356 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
357 // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8
358 // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8
359 // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8
360
361 // CHECK-NEXT: call void @_ZN7Elision3fooEv()
362 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
363 A i = (foo(), A());
364
365 // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
366 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
367 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
368 A j = (fooA(), A());
369
370 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
371 // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
372 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
373 A k = (A(), fooA());
374
375 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
376 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
377 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
378 }
379
380
381 // CHECK: define void @_ZN7Elision5test1EbNS_1AE(
test1(bool c,A x)382 void test1(bool c, A x) {
383 // CHECK: [[I:%.*]] = alloca [[A]], align 8
384 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
385
386 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
387 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
388 A i = (c ? A() : x);
389
390 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
391 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
392 A j = (c ? x : A());
393
394 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
395 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
396 }
397
398 // CHECK: define void @_ZN7Elision5test2Ev([[A]]* sret
test2()399 A test2() {
400 // CHECK: call void @_ZN7Elision3fooEv()
401 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
402 // CHECK-NEXT: ret void
403 return (foo(), A());
404 }
405
406 // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* sret
test3(int v,A x)407 A test3(int v, A x) {
408 if (v < 5)
409 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
410 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
411 return (v < 0 ? A() : x);
412 else
413 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
414 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
415 return (v > 10 ? x : A());
416
417 // CHECK: ret void
418 }
419
420 // CHECK: define void @_ZN7Elision5test4Ev()
test4()421 void test4() {
422 // CHECK: [[X:%.*]] = alloca [[A]], align 8
423 // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
424
425 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
426 A x;
427
428 // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
429 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
430 // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
431 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
432 A xs[] = { A(), x };
433
434 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
435 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2
436 // CHECK-NEXT: br label
437 // CHECK: [[AFTER:%.*]] = phi [[A]]*
438 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
439 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
440 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
441 // CHECK-NEXT: br i1 [[T0]],
442
443 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
444 }
445
446 // rdar://problem/8433352
447 // CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret
448 struct B { A a; B(); };
test5()449 A test5() {
450 // CHECK: [[AT0:%.*]] = alloca [[A]], align 8
451 // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
452 // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
453 // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
454 // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
455
456 // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
457 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
458 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
459 // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
460 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
461 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
462 takeA(B().a);
463
464 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
465 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
466 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
467 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
468 A x = B().a;
469
470 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
471 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
472 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
473 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
474 return B().a;
475
476 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
477 }
478
479 // Reduced from webkit.
480 // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]*
481 struct C { operator A() const; };
test6(const C * x)482 void test6(const C *x) {
483 // CHECK: [[T0:%.*]] = alloca [[A]], align 8
484 // CHECK: [[X:%.*]] = load [[C]]** {{%.*}}, align 8
485 // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]])
486 // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]])
487 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
488 // CHECK-NEXT: ret void
489 A(*x).foo();
490 }
491 }
492
493 namespace PR8623 {
494 struct A { A(int); ~A(); };
495
496 // CHECK: define void @_ZN6PR86233fooEb(
foo(bool b)497 void foo(bool b) {
498 // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
499 // CHECK-NEXT: [[LCONS:%.*]] = alloca i1
500 // CHECK-NEXT: [[RCONS:%.*]] = alloca i1
501 // CHECK: store i1 false, i1* [[LCONS]]
502 // CHECK-NEXT: store i1 false, i1* [[RCONS]]
503 // CHECK-NEXT: br i1
504 // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
505 // CHECK-NEXT: store i1 true, i1* [[LCONS]]
506 // CHECK-NEXT: br label
507 // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
508 // CHECK-NEXT: store i1 true, i1* [[RCONS]]
509 // CHECK-NEXT: br label
510 // CHECK: load i1* [[RCONS]]
511 // CHECK-NEXT: br i1
512 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
513 // CHECK-NEXT: br label
514 // CHECK: load i1* [[LCONS]]
515 // CHECK-NEXT: br i1
516 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
517 // CHECK-NEXT: br label
518 // CHECK: ret void
519 b ? A(2) : A(3);
520 }
521 }
522