1 | // RUN: %clang_cc1 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | struct A { int x; A(int); ~A(); }; |
4 | A f() { return A(0); } |
5 | // CHECK-LABEL: define void @_Z1fv |
6 | // CHECK: call {{.*}} @_ZN1AC1Ei |
7 | // CHECK-NEXT: ret void |
8 | |
9 | // Verify that we do not elide copies when constructing a base class. |
10 | namespace no_elide_base { |
11 | struct Base { |
12 | Base(const Base&); |
13 | ~Base(); |
14 | }; |
15 | |
16 | struct Other { |
17 | operator Base() const; |
18 | }; |
19 | |
20 | struct Derived : public virtual Base { |
21 | Derived(const Other &O); |
22 | }; |
23 | |
24 | // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* dereferenceable({{[0-9]+}}) %O) unnamed_addr |
25 | Derived::Derived(const Other &O) |
26 | // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv |
27 | // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_ |
28 | // CHECK: call {{.*}} @_ZN13no_elide_base4BaseD1Ev |
29 | : Base(O) |
30 | { |
31 | // CHECK: ret |
32 | } |
33 | } |
34 | |
35 | // PR8683. |
36 | |
37 | namespace PR8683 { |
38 | |
39 | struct A { |
40 | A(); |
41 | A(const A&); |
42 | A& operator=(const A&); |
43 | }; |
44 | |
45 | struct B { |
46 | A a; |
47 | }; |
48 | |
49 | void f() { |
50 | // Verify that we don't mark the copy constructor in this expression as elidable. |
51 | // CHECK: call {{.*}} @_ZN6PR86831AC1ERKS0_ |
52 | A a = (B().a); |
53 | } |
54 | |
55 | } |
56 | |
57 | namespace PR12139 { |
58 | struct A { |
59 | A() : value(1) { } |
60 | A(A const &, int value = 2) : value(value) { } |
61 | int value; |
62 | |
63 | static A makeA() { A a; a.value = 2; return a; } |
64 | }; |
65 | |
66 | // CHECK-LABEL: define i32 @_ZN7PR121394testEv |
67 | int test() { |
68 | // CHECK: call void @_ZN7PR121391A5makeAEv |
69 | // CHECK-NEXT: call %"struct.PR12139::A"* @_ZN7PR121391AC1ERKS0_i |
70 | A a(A::makeA(), 3); |
71 | // CHECK-NEXT: getelementptr inbounds |
72 | // CHECK-NEXT: load |
73 | // CHECK-NEXT: ret i32 |
74 | return a.value; |
75 | } |
76 | } |
77 | |
78 | namespace ElidableCallIsNotCopyCtor { |
79 | struct A { A(const A&); }; |
80 | struct B : A { |
81 | B(B&); |
82 | B(A); |
83 | B(int); |
84 | }; |
85 | void f() { |
86 | // Here, we construct via B(int) then B(A). The B(A) construction is |
87 | // elidable, but we don't have an AST representation for the case where we |
88 | // must elide not only a constructor call but also some argument |
89 | // conversions, so we don't elide it. |
90 | // CHECK-LABEL: define void @_ZN25ElidableCallIsNotCopyCtor1fEv( |
91 | // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1Ei( |
92 | // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1AC1ERKS0_( |
93 | // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1ENS_1AE( |
94 | B b = 0; |
95 | } |
96 | } |
97 | |