Home | History | Annotate | Download | only in CodeGenCXX
      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