1 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | |
4 | struct Spacer { int x; }; |
5 | struct A { double array[2]; }; |
6 | struct B : Spacer, A { }; |
7 | |
8 | B &getB(); |
9 | |
10 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.A* @_Z4getAv() |
11 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.B* @_Z4getBv() |
12 | // CHECK-NEXT: bitcast %struct.B* |
13 | // CHECK-NEXT: getelementptr inbounds i8, i8* |
14 | // CHECK-NEXT: bitcast i8* {{.*}} to %struct.A* |
15 | // CHECK-NEXT: ret %struct.A* |
16 | A &&getA() { return static_cast<A&&>(getB()); } |
17 | |
18 | int &getIntLValue(); |
19 | int &&getIntXValue(); |
20 | int getIntPRValue(); |
21 | |
22 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f0v() |
23 | // CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntLValuev() |
24 | // CHECK-NEXT: ret i32* |
25 | int &&f0() { return static_cast<int&&>(getIntLValue()); } |
26 | |
27 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f1v() |
28 | // CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntXValuev() |
29 | // CHECK-NEXT: ret i32* |
30 | int &&f1() { return static_cast<int&&>(getIntXValue()); } |
31 | |
32 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f2v |
33 | // CHECK: call i32 @_Z13getIntPRValuev() |
34 | // CHECK-NEXT: store i32 {{.*}}, i32* |
35 | // CHECK-NEXT: ret i32* |
36 | int &&f2() { return static_cast<int&&>(getIntPRValue()); } |
37 | |
38 | bool ok; |
39 | |
40 | class C |
41 | { |
42 | int* state_; |
43 | |
44 | C(const C&) = delete; |
45 | C& operator=(const C&) = delete; |
46 | public: |
47 | C(int state) : state_(new int(state)) { } |
48 | |
49 | C(C&& a) { |
50 | state_ = a.state_; |
51 | a.state_ = 0; |
52 | } |
53 | |
54 | ~C() { |
55 | delete state_; |
56 | state_ = 0; |
57 | } |
58 | }; |
59 | |
60 | C test(); |
61 | |
62 | // CHECK-LABEL: define void @_Z15elide_copy_initv |
63 | void elide_copy_init() { |
64 | ok = false; |
65 | // CHECK: call void @_Z4testv |
66 | C a = test(); |
67 | // CHECK-NEXT: call void @_ZN1CD1Ev |
68 | // CHECK-NEXT: ret void |
69 | } |
70 | |
71 | // CHECK-LABEL: define void @_Z16test_move_returnv |
72 | C test_move_return() { |
73 | // CHECK: call void @_ZN1CC1Ei |
74 | C a1(3); |
75 | // CHECK: call void @_ZN1CC1Ei |
76 | C a2(4); |
77 | if (ok) |
78 | // CHECK: call void @_ZN1CC1EOS_ |
79 | return a1; |
80 | // CHECK: call void @_ZN1CC1EOS_ |
81 | return a2; |
82 | // CHECK: call void @_ZN1CD1Ev |
83 | // CHECK: call void @_ZN1CD1Ev |
84 | //CHECK: ret void |
85 | } |
86 | |
87 | // PR10800: don't crash |
88 | namespace test1 { |
89 | int &&move(int&); |
90 | |
91 | struct A { A(int); }; |
92 | struct B { |
93 | A a; |
94 | B(int i); |
95 | }; |
96 | |
97 | // CHECK-LABEL: define void @_ZN5test11BC2Ei( |
98 | // CHECK: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) i32* @_ZN5test14moveERi( |
99 | // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[T0]] |
100 | // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]]) |
101 | // CHECK-NEXT: ret void |
102 | B::B(int i) : a(move(i)) {} |
103 | } |
104 | |
105 | // PR11009 |
106 | struct MoveConvertible { |
107 | operator int&& () const; |
108 | }; |
109 | void moveConstruct() { |
110 | (void)(int)MoveConvertible(); |
111 | } |
112 | |