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