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