2011-10-14 06:29:44 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
|
2011-01-26 00:13:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
struct Spacer { int x; };
|
|
|
|
struct A { double array[2]; };
|
|
|
|
struct B : Spacer, A { };
|
|
|
|
|
|
|
|
B &getB();
|
|
|
|
|
2014-07-18 23:52:10 +08:00
|
|
|
// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.A* @_Z4getAv()
|
|
|
|
// CHECK: call dereferenceable({{[0-9]+}}) %struct.B* @_Z4getBv()
|
2011-01-26 00:13:26 +08:00
|
|
|
// CHECK-NEXT: bitcast %struct.B*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK-NEXT: getelementptr inbounds i8, i8*
|
2011-01-26 00:13:26 +08:00
|
|
|
// CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
|
|
|
|
// CHECK-NEXT: ret %struct.A*
|
|
|
|
A &&getA() { return static_cast<A&&>(getB()); }
|
|
|
|
|
|
|
|
int &getIntLValue();
|
|
|
|
int &&getIntXValue();
|
|
|
|
int getIntPRValue();
|
|
|
|
|
2014-07-18 23:52:10 +08:00
|
|
|
// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f0v()
|
|
|
|
// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntLValuev()
|
2011-01-26 00:13:26 +08:00
|
|
|
// CHECK-NEXT: ret i32*
|
|
|
|
int &&f0() { return static_cast<int&&>(getIntLValue()); }
|
|
|
|
|
2014-07-18 23:52:10 +08:00
|
|
|
// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f1v()
|
|
|
|
// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntXValuev()
|
2011-01-26 00:13:26 +08:00
|
|
|
// CHECK-NEXT: ret i32*
|
|
|
|
int &&f1() { return static_cast<int&&>(getIntXValue()); }
|
|
|
|
|
2014-07-18 23:52:10 +08:00
|
|
|
// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f2v
|
2011-01-26 00:13:26 +08:00
|
|
|
// CHECK: call i32 @_Z13getIntPRValuev()
|
|
|
|
// CHECK-NEXT: store i32 {{.*}}, i32*
|
|
|
|
// CHECK-NEXT: ret i32*
|
|
|
|
int &&f2() { return static_cast<int&&>(getIntPRValue()); }
|
2011-01-28 07:22:05 +08:00
|
|
|
|
|
|
|
bool ok;
|
|
|
|
|
|
|
|
class C
|
|
|
|
{
|
|
|
|
int* state_;
|
|
|
|
|
|
|
|
C(const C&) = delete;
|
|
|
|
C& operator=(const C&) = delete;
|
|
|
|
public:
|
|
|
|
C(int state) : state_(new int(state)) { }
|
|
|
|
|
|
|
|
C(C&& a) {
|
|
|
|
state_ = a.state_;
|
|
|
|
a.state_ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
~C() {
|
|
|
|
delete state_;
|
|
|
|
state_ = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
C test();
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_Z15elide_copy_initv
|
2011-01-28 07:22:05 +08:00
|
|
|
void elide_copy_init() {
|
|
|
|
ok = false;
|
2011-01-28 07:24:55 +08:00
|
|
|
// CHECK: call void @_Z4testv
|
2011-01-28 07:22:05 +08:00
|
|
|
C a = test();
|
2011-01-28 07:24:55 +08:00
|
|
|
// CHECK-NEXT: call void @_ZN1CD1Ev
|
|
|
|
// CHECK-NEXT: ret void
|
2011-01-28 07:22:05 +08:00
|
|
|
}
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_Z16test_move_returnv
|
2011-01-28 07:22:05 +08:00
|
|
|
C test_move_return() {
|
|
|
|
// CHECK: call void @_ZN1CC1Ei
|
|
|
|
C a1(3);
|
|
|
|
// CHECK: call void @_ZN1CC1Ei
|
|
|
|
C a2(4);
|
|
|
|
if (ok)
|
|
|
|
// CHECK: call void @_ZN1CC1EOS_
|
|
|
|
return a1;
|
|
|
|
// CHECK: call void @_ZN1CC1EOS_
|
|
|
|
return a2;
|
|
|
|
// CHECK: call void @_ZN1CD1Ev
|
|
|
|
// CHECK: call void @_ZN1CD1Ev
|
|
|
|
//CHECK: ret void
|
|
|
|
}
|
2011-08-30 08:57:29 +08:00
|
|
|
|
|
|
|
// PR10800: don't crash
|
|
|
|
namespace test1 {
|
|
|
|
int &&move(int&);
|
|
|
|
|
|
|
|
struct A { A(int); };
|
|
|
|
struct B {
|
|
|
|
A a;
|
|
|
|
B(int i);
|
|
|
|
};
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_ZN5test11BC2Ei(
|
2014-07-18 23:52:10 +08:00
|
|
|
// CHECK: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) i32* @_ZN5test14moveERi(
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[T0]]
|
2011-08-30 08:57:29 +08:00
|
|
|
// CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]])
|
|
|
|
// CHECK-NEXT: ret void
|
|
|
|
B::B(int i) : a(move(i)) {}
|
|
|
|
}
|
2011-09-28 02:55:06 +08:00
|
|
|
|
|
|
|
// PR11009
|
|
|
|
struct MoveConvertible {
|
|
|
|
operator int&& () const;
|
|
|
|
};
|
|
|
|
void moveConstruct() {
|
|
|
|
(void)(int)MoveConvertible();
|
|
|
|
}
|