]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCXX/warn-range-loop-analysis.cpp
Vendor import of clang trunk r238337:
[FreeBSD/FreeBSD.git] / test / SemaCXX / warn-range-loop-analysis.cpp
1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s
3
4 template <typename return_type>
5 struct Iterator {
6   return_type operator*();
7   Iterator operator++();
8   bool operator!=(const Iterator);
9 };
10
11 template <typename T>
12 struct Container {
13   typedef Iterator<T> I;
14
15   I begin();
16   I end();
17 };
18
19 struct Foo {};
20 struct Bar {
21   Bar(Foo);
22   Bar(int);
23   operator int();
24 };
25
26 // Testing notes:
27 // test0 checks that the full text of the warnings and notes is correct.  The
28 //   rest of the tests checks a smaller portion of the text.
29 // test1-6 are set in pairs, the odd numbers are the non-reference returning
30 //   versions of the even numbers.
31 // test7-9 use an array instead of a range object
32 // tests use all four versions of the loop varaible, const &T, const T, T&, and
33 //   T.  Versions producing errors and are commented out.
34 //
35 // Conversion chart:
36 //   double <=> int
37 //   int    <=> Bar
38 //   double  => Bar
39 //   Foo     => Bar
40 //
41 // Conversions during tests:
42 // test1-2
43 //   int => int
44 //   int => double
45 //   int => Bar
46 // test3-4
47 //   Bar => Bar
48 //   Bar => int
49 // test5-6
50 //   Foo => Bar
51 // test7
52 //   double => double
53 //   double => int
54 //   double => Bar
55 // test8
56 //   Foo => Foo
57 //   Foo => Bar
58 // test9
59 //   Bar => Bar
60 //   Bar => int
61
62 void test0() {
63   Container<int> int_non_ref_container;
64   Container<int&> int_container;
65   Container<Bar&> bar_container;
66
67   for (const int &x : int_non_ref_container) {}
68   // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}}
69   // expected-note@-2 {{use non-reference type 'int'}}
70
71   for (const double &x : int_container) {}
72   // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}}
73   // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}}
74
75   for (const Bar x : bar_container) {}
76   // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}}
77   // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}}
78 }
79
80 void test1() {
81   Container<int> A;
82
83   for (const int &x : A) {}
84   // expected-warning@-1 {{always a copy}}
85   // expected-note@-2 {{'int'}}
86   for (const int x : A) {}
87   // No warning, non-reference type indicates copy is made
88   //for (int &x : A) {}
89   // Binding error
90   for (int x : A) {}
91   // No warning, non-reference type indicates copy is made
92
93   for (const double &x : A) {}
94   // expected-warning@-1 {{always a copy}}
95   // expected-note@-2 {{'double'}}
96   for (const double x : A) {}
97   // No warning, non-reference type indicates copy is made
98   //for (double &x : A) {}
99   // Binding error
100   for (double x : A) {}
101   // No warning, non-reference type indicates copy is made
102
103   for (const Bar &x : A) {}
104   // expected-warning@-1 {{always a copy}}
105   // expected-note@-2 {{'Bar'}}
106   for (const Bar x : A) {}
107   // No warning, non-reference type indicates copy is made
108   //for (Bar &x : A) {}
109   // Binding error
110   for (Bar x : A) {}
111   // No warning, non-reference type indicates copy is made
112 }
113
114 void test2() {
115   Container<int&> B;
116
117   for (const int &x : B) {}
118   // No warning, this reference is not a temporary
119   for (const int x : B) {}
120   // No warning on POD copy
121   for (int &x : B) {}
122   // No warning
123   for (int x : B) {}
124   // No warning
125
126   for (const double &x : B) {}
127   // expected-warning@-1 {{resulting in a copy}}
128   // expected-note-re@-2 {{'double'{{.*}}'const int &'}}
129   for (const double x : B) {}
130   //for (double &x : B) {}
131   // Binding error
132   for (double x : B) {}
133   // No warning
134
135   for (const Bar &x : B) {}
136   // expected-warning@-1 {{resulting in a copy}}
137   // expected-note@-2 {{'Bar'}}
138   for (const Bar x : B) {}
139   //for (Bar &x : B) {}
140   // Binding error
141   for (Bar x : B) {}
142   // No warning
143 }
144
145 void test3() {
146   Container<Bar> C;
147
148   for (const Bar &x : C) {}
149   // expected-warning@-1 {{always a copy}}
150   // expected-note@-2 {{'Bar'}}
151   for (const Bar x : C) {}
152   // No warning, non-reference type indicates copy is made
153   //for (Bar &x : C) {}
154   // Binding error
155   for (Bar x : C) {}
156   // No warning, non-reference type indicates copy is made
157
158   for (const int &x : C) {}
159   // expected-warning@-1 {{always a copy}}
160   // expected-note@-2 {{'int'}}
161   for (const int x : C) {}
162   // No warning, copy made
163   //for (int &x : C) {}
164   // Binding error
165   for (int x : C) {}
166   // No warning, copy made
167 }
168
169 void test4() {
170   Container<Bar&> D;
171
172   for (const Bar &x : D) {}
173   // No warning, this reference is not a temporary
174   for (const Bar x : D) {}
175   // expected-warning@-1 {{creates a copy}}
176   // expected-note@-2 {{'const Bar &'}}
177   for (Bar &x : D) {}
178   // No warning
179   for (Bar x : D) {}
180   // No warning
181
182   for (const int &x : D) {}
183   // expected-warning@-1 {{resulting in a copy}}
184   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
185   for (const int x : D) {}
186   // No warning
187   //for (int &x : D) {}
188   // Binding error
189   for (int x : D) {}
190   // No warning
191 }
192
193 void test5() {
194   Container<Foo> E;
195
196   for (const Bar &x : E) {}
197   // expected-warning@-1 {{always a copy}}
198   // expected-note@-2 {{'Bar'}}
199   for (const Bar x : E) {}
200   // No warning, non-reference type indicates copy is made
201   //for (Bar &x : E) {}
202   // Binding error
203   for (Bar x : E) {}
204   // No warning, non-reference type indicates copy is made
205 }
206
207 void test6() {
208   Container<Foo&> F;
209
210   for (const Bar &x : F) {}
211   // expected-warning@-1 {{resulting in a copy}}
212   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
213   for (const Bar x : F) {}
214   // No warning.
215   //for (Bar &x : F) {}
216   // Binding error
217   for (Bar x : F) {}
218   // No warning
219 }
220
221 void test7() {
222   double G[2];
223
224   for (const double &x : G) {}
225   // No warning
226   for (const double x : G) {}
227   // No warning on POD copy
228   for (double &x : G) {}
229   // No warning
230   for (double x : G) {}
231   // No warning
232
233   for (const int &x : G) {}
234   // expected-warning@-1 {{resulting in a copy}}
235   // expected-note-re@-2 {{'int'{{.*}}'const double &'}}
236   for (const int x : G) {}
237   // No warning
238   //for (int &x : G) {}
239   // Binding error
240   for (int x : G) {}
241   // No warning
242
243   for (const Bar &x : G) {}
244   // expected-warning@-1 {{resulting in a copy}}
245   // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}}
246   for (const Bar x : G) {}
247   // No warning
248   //for (int &Bar : G) {}
249   // Binding error
250   for (int Bar : G) {}
251   // No warning
252 }
253
254 void test8() {
255   Foo H[2];
256
257   for (const Foo &x : H) {}
258   // No warning
259   for (const Foo x : H) {}
260   // No warning on POD copy
261   for (Foo &x : H) {}
262   // No warning
263   for (Foo x : H) {}
264   // No warning
265
266   for (const Bar &x : H) {}
267   // expected-warning@-1 {{resulting in a copy}}
268   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
269   for (const Bar x : H) {}
270   // No warning
271   //for (Bar &x: H) {}
272   // Binding error
273   for (Bar x: H) {}
274   // No warning
275 }
276
277 void test9() {
278   Bar I[2] = {1,2};
279
280   for (const Bar &x : I) {}
281   // No warning
282   for (const Bar x : I) {}
283   // expected-warning@-1 {{creates a copy}}
284   // expected-note@-2 {{'const Bar &'}}
285   for (Bar &x : I) {}
286   // No warning
287   for (Bar x : I) {}
288   // No warning
289
290   for (const int &x : I) {}
291   // expected-warning@-1 {{resulting in a copy}}
292   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
293   for (const int x : I) {}
294   // No warning
295   //for (int &x : I) {}
296   // Binding error
297   for (int x : I) {}
298   // No warning
299 }