brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · e234977 Raw
237 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s2 3// Test the c++0x-specific reference initialization rules, e.g., the4// rules for rvalue references.5template<typename T> T prvalue();6template<typename T> T&& xvalue();7template<typename T> T& lvalue();8 9struct Base { };10struct Derived : Base { };11 12struct HasArray {13  int array[5];14};15 16int f(int);17 18template<typename T>19struct ConvertsTo {20  operator T(); // expected-note 2{{candidate function}}21};22 23void test_rvalue_refs() {24  // If the initializer expression...25  //   - is an xvalue, class prvalue, array prvalue or function lvalue26  //     and "cv1 T1" is reference-compatible with "cv2 T2", or27 28  // xvalue case29  Base&& base0 = xvalue<Base>();30  Base&& base1 = xvalue<Derived>();31  int&& int0 = xvalue<int>();32 33  // class prvalue case34  Base&& base2 = prvalue<Base>();35  Base&& base3 = prvalue<Derived>();36 37  // array prvalue case38  int (&&array0)[5] = HasArray().array;39 40  // function lvalue case41  int (&&function0)(int) = f;42 43  //   - has a class type (i.e., T2 is a class type), where T1 is not44  //     reference-related to T2, and can be implicitly converted to45  //     an xvalue, class prvalue, or function lvalue of type "cv346  //     T3", where "cv1 T1" is reference-compatible with "cv3 T3",47 48  // xvalue49  Base&& base4 = ConvertsTo<Base&&>();50  Base&& base5 = ConvertsTo<Derived&&>();51  int && int1 = ConvertsTo<int&&>();52 53  // class prvalue54  Base&& base6 = ConvertsTo<Base>();55  Base&& base7 = ConvertsTo<Derived>();56 57  // function lvalue58  int (&&function1)(int) = ConvertsTo<int(&)(int)>();59 60  // In the second case, if the reference is an rvalue reference and61  // the second standard conversion sequence of the user-defined62  // conversion sequence includes an lvalue-to-rvalue conversion, the63  // program is ill-formed.64  int &&int2 = ConvertsTo<int&>(); // expected-error{{no viable conversion from 'ConvertsTo<int &>' to 'int'}}65  int &&int3 = ConvertsTo<float&>(); // expected-error{{no viable conversion from 'ConvertsTo<float &>' to 'int'}}66}67 68class NonCopyable {69  NonCopyable(const NonCopyable&);70};71 72class NonCopyableDerived : public NonCopyable {73  NonCopyableDerived(const NonCopyableDerived&);74};75 76// Make sure we get direct bindings with no copies.77void test_direct_binding() {78  NonCopyable &&nc0 = prvalue<NonCopyable>();79  NonCopyable &&nc1 = prvalue<NonCopyableDerived>();80  NonCopyable &&nc2 = xvalue<NonCopyable>();81  NonCopyable &&nc3 = xvalue<NonCopyableDerived>();82  const NonCopyable &nc4 = prvalue<NonCopyable>();83  const NonCopyable &nc5 = prvalue<NonCopyableDerived>();84  const NonCopyable &nc6 = xvalue<NonCopyable>();85  const NonCopyable &nc7 = xvalue<NonCopyableDerived>();86  NonCopyable &&nc8 = ConvertsTo<NonCopyable&&>();87  NonCopyable &&nc9 = ConvertsTo<NonCopyableDerived&&>();88  const NonCopyable &nc10 = ConvertsTo<NonCopyable&&>();89  const NonCopyable &nc11 = ConvertsTo<NonCopyableDerived&&>();90}91 92namespace std_example_1 {93  double d = 2.0; 94  double& rd = d; 95  const double& rcd = d;96  struct A { }; 97  struct B : A { 98    operator int&();99  } b;100  A& ra = b; 101  const A& rca = b; 102  int& ir = B();103}104 105namespace std_example_2 {106  double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}}107  int i = 2; 108  double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}109  struct A { }; 110  struct B : A { } b; 111  extern B f(); 112  const A& rca = f(); 113  A&& rra = f();114  struct X { 115    operator B();  // expected-note{{candidate function}}116    operator int&(); // expected-note{{candidate function}}117  } x;118  const A& r = x;119  int&& rri = static_cast<int&&>(i);120  B&& rrb = x;121  int&& rri2 = X(); // expected-error{{no viable conversion from 'X' to 'int'}}122 123  const double& rcd2 = 2;124  double&& rrd = 2;125  const volatile int cvi = 1;126  const int& r2 = cvi; // expected-error{{binding reference of type 'const int' to value of type 'const volatile int' drops 'volatile' qualifier}}127 128  double d;129  double&& rrd2 = d; // expected-error{{rvalue reference to type 'double' cannot bind to lvalue of type 'double'}}130  double&& rrd3 = i;131}132 133namespace argument_passing {134  void base_rvalue_ref(Base&&);135  void int_rvalue_ref(int&&); // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo<int &>' to 'int &&' for 1st argument}} \136  // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo<float &>' to 'int &&' for 1st argument}}137 138  void array_rvalue_ref(int (&&)[5]);139  void function_rvalue_ref(int (&&)(int));140 141  void test() {142    base_rvalue_ref(xvalue<Base>());143    base_rvalue_ref(xvalue<Derived>());144    int_rvalue_ref(xvalue<int>());145    146    base_rvalue_ref(prvalue<Base>());147    base_rvalue_ref(prvalue<Derived>());148    149    array_rvalue_ref(HasArray().array);150    151    function_rvalue_ref(f);152    153    base_rvalue_ref(ConvertsTo<Base&&>());154    base_rvalue_ref(ConvertsTo<Derived&&>());155    int_rvalue_ref(ConvertsTo<int&&>());156    157    base_rvalue_ref(ConvertsTo<Base>());158    base_rvalue_ref(ConvertsTo<Derived>());159 160    function_rvalue_ref(ConvertsTo<int(&)(int)>());161    162    int_rvalue_ref(ConvertsTo<int&>()); // expected-error{{no matching function for call to 'int_rvalue_ref'}}163    int_rvalue_ref(ConvertsTo<float&>()); // expected-error{{no matching function for call to 'int_rvalue_ref'}}164  }165 166}167 168namespace pr10644 {169  struct string {170    string(const char* __s);171  };172  class map {173    int& operator[](const string& __k);174  public:175    int& operator[](const string&& __k);176  };177  void foo() {178    static map key_map;179    key_map["line"];180  }181}182 183namespace PR11003 {184  class Value {185  };186  struct MoveRef {187    operator Value &() const ;188  };189  MoveRef Move(int);190  void growTo() {191    Value x = Move(0);192    Value y(Move(0));193  }194}195 196namespace rdar13278115 {197  struct X { };198  struct Y : X { };199  X &&f0(X &x) { return x; } // expected-error{{rvalue reference to type 'X' cannot bind to lvalue of type 'X'}}200  X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'X' cannot bind to lvalue of type 'Y'}}201  const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const X' cannot bind to lvalue of type 'Y'}}202}203 204namespace bitfields {205  struct IntBitfield {206    int i : 17; // expected-note 3 {{bit-field is declared here}}207  };208 209  // A simplified version of std::move.210  template <typename T>211  T &&move(T &obj) {212    return static_cast<T &&>(obj);213  }214 215  void test() {216    int & ir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}217    int & ir2 = (xvalue<IntBitfield>().i); // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}218    int && ir3 = (xvalue<IntBitfield>().i); // no-warning219    int && ir4 = move(lvalue<IntBitfield>()).i; // no-warning220 221    volatile int & vir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}222    volatile int & vir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'volatile int' cannot bind to a temporary of type 'int'}}223    volatile int && vir3 = (xvalue<IntBitfield>().i); // no-warning224    volatile int && vir4 = move(lvalue<IntBitfield>()).i; // no-warning225 226    const int & cir1 = (lvalue<IntBitfield>().i); // no-warning227    const int & cir2 = (xvalue<IntBitfield>().i); // no-warning228    const int && cir3 = (xvalue<IntBitfield>().i); // no-warning229    const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning230 231    const volatile int & cvir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}232    const volatile int & cvir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}233    const volatile int && cvir3 = (xvalue<IntBitfield>().i); // no-warning234    const volatile int && cvir4 = move(lvalue<IntBitfield>()).i; // no-warning235  }236}237