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