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