1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s |
2 | |
3 | // Test the c++0x-specific reference initialization rules, e.g., the |
4 | // rules for rvalue references. |
5 | template<typename T> T prvalue(); |
6 | template<typename T> T&& xvalue(); |
7 | template<typename T> T& lvalue(); |
8 | |
9 | struct Base { }; |
10 | struct Derived : Base { }; |
11 | |
12 | struct HasArray { |
13 | int array[5]; |
14 | }; |
15 | |
16 | int f(int); |
17 | |
18 | template<typename T> |
19 | struct ConvertsTo { |
20 | operator T(); // expected-note 2{{candidate function}} |
21 | }; |
22 | |
23 | void 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 | |
68 | class NonCopyable { |
69 | NonCopyable(const NonCopyable&); |
70 | }; |
71 | |
72 | class NonCopyableDerived : public NonCopyable { |
73 | NonCopyableDerived(const NonCopyableDerived&); |
74 | }; |
75 | |
76 | // Make sure we get direct bindings with no copies. |
77 | void 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 | |
92 | namespace 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 | |
105 | namespace 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 'std_example_2::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 value of type 'const volatile int' to reference to type 'const 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 | |
133 | namespace 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 | |
168 | namespace 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 | |
183 | namespace 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 | |
196 | namespace rdar13278115 { |
197 | struct X { }; |
198 | struct Y : X { }; |
199 | X &&f0(X &x) { return x; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::X'}} |
200 | X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} |
201 | const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} |
202 | } |
203 | |
204 | namespace 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-warning |
219 | int && ir4 = move(lvalue<IntBitfield>()).i; // no-warning |
220 | |
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-warning |
224 | volatile int && vir4 = move(lvalue<IntBitfield>()).i; // no-warning |
225 | |
226 | const int & cir1 = (lvalue<IntBitfield>().i); // no-warning |
227 | const int & cir2 = (xvalue<IntBitfield>().i); // no-warning |
228 | const int && cir3 = (xvalue<IntBitfield>().i); // no-warning |
229 | const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning |
230 | |
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-warning |
234 | const volatile int && cvir4 = move(lvalue<IntBitfield>()).i; // no-warning |
235 | } |
236 | } |
237 | |