p5-0x.cpp revision b2855ad68d93824faf47c09bbef90ba74157f0f4
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify -pedantic %s 2 3// Test the C++0x-specific reference initialization rules, e.g., the 4// 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 lvalue 26 // and "cv1 T1" is reference-compatible with "cv2 T2", or 27 28 // xvalue case 29 Base&& base0 = xvalue<Base>(); 30 Base&& base1 = xvalue<Derived>(); 31 int&& int0 = xvalue<int>(); 32 33 // class prvalue case 34 Base&& base2 = prvalue<Base>(); 35 Base&& base3 = prvalue<Derived>(); 36 37 // array prvalue case 38 int (&&array0)[5] = HasArray().array; 39 40 // function lvalue case 41 int (&&function0)(int) = f; 42 43 // - has a class type (i.e., T2 is a class type), where T1 is not 44 // reference-related to T2, and can be implicitly converted to 45 // an xvalue, class prvalue, or function lvalue of type "cv3 46 // T3", where "cv1 T1" is reference-compatible with "cv3 T3", 47 48 // xvalue 49 Base&& base4 = ConvertsTo<Base&&>(); 50 Base&& base5 = ConvertsTo<Derived&&>(); 51 int && int1 = ConvertsTo<int&&>(); 52 53 // class prvalue 54 Base&& base6 = ConvertsTo<Base>(); 55 Base&& base7 = ConvertsTo<Derived>(); 56 57 // function lvalue 58 int (&&function1)(int) = ConvertsTo<int(&)(int)>(); 59 60 // In the second case, if the reference is an rvalue reference and 61 // the second standard conversion sequence of the user-defined 62 // conversion sequence includes an lvalue-to-rvalue conversion, the 63 // 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 { 93 struct A { }; 94 struct B : A { } b; 95 extern B f(); 96 const A& rca = f(); 97 A&& rra = f(); 98 struct X { 99 operator B(); // expected-note{{candidate function}} 100 operator int&(); // expected-note{{candidate function}} 101 } x; 102 const A& r = x; 103 int i; 104 int&& rri = static_cast<int&&>(i); 105 B&& rrb = x; 106 int&& rri2 = X(); // expected-error{{no viable conversion from 'std_example::X' to 'int'}} 107} 108