]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
[FreeBSD/FreeBSD.git] / test / CXX / dcl.decl / dcl.init / dcl.init.ref / p5-0x.cpp
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 of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}}
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 }