1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wall -Wrange-loop-bind-reference -Wno-unused -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s
3 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s
4 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
5 
6 template <typename return_type>
7 struct Iterator {
8   return_type operator*();
9   Iterator operator++();
10   bool operator!=(const Iterator);
11 };
12 
13 template <typename T>
14 struct Container {
15   typedef Iterator<T> I;
16 
17   I begin();
18   I end();
19 };
20 
21 struct Foo {};
22 struct Bar {
23   // Small trivially copyable types do not show a warning when copied in a
24   // range-based for loop. This size ensures the object is not considered
25   // small.
26   char s[128];
27   Bar(Foo);
28   Bar(int);
29   operator int();
30 };
31 
32 // Testing notes:
33 // test0 checks that the full text of the warnings and notes is correct.  The
34 //   rest of the tests checks a smaller portion of the text.
35 // test1-6 are set in pairs, the odd numbers are the non-reference returning
36 //   versions of the even numbers.
37 // test7-9 use an array instead of a range object
38 // tests use all four versions of the loop variable, const &T, const T, T&, and
39 //   T.  Versions producing errors and are commented out.
40 //
41 // Conversion chart:
42 //   double <=> int
43 //   int    <=> Bar
44 //   double  => Bar
45 //   Foo     => Bar
46 //
47 // Conversions during tests:
48 // test1-2
49 //   int => int
50 //   int => double
51 //   int => Bar
52 // test3-4
53 //   Bar => Bar
54 //   Bar => int
55 // test5-6
56 //   Foo => Bar
57 // test7
58 //   double => double
59 //   double => int
60 //   double => Bar
61 // test8
62 //   Foo => Foo
63 //   Foo => Bar
64 // test9
65 //   Bar => Bar
66 //   Bar => int
67 
test0()68 void test0() {
69   Container<int> int_non_ref_container;
70   Container<int&> int_container;
71   Container<Bar&> bar_container;
72 
73   for (const int &x : int_non_ref_container) {}
74   // expected-warning@-1 {{loop variable 'x' binds to a temporary value produced by a range of type 'Container<int>'}}
75   // expected-note@-2 {{use non-reference type 'int'}}
76   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
77 
78   for (const double &x : int_container) {}
79   // expected-warning@-1 {{loop variable 'x' of type 'const double &' binds to a temporary constructed from type 'int &'}}
80   // expected-note@-2 {{use non-reference type 'double' to make construction explicit or type 'const int &' to prevent copying}}
81   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:""
82 
83   for (const Bar x : bar_container) {}
84   // expected-warning@-1 {{loop variable 'x' creates a copy from type 'const Bar'}}
85   // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}}
86   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&"
87 }
88 
test1()89 void test1() {
90   Container<int> A;
91 
92   for (const int &&x : A) {}
93   // No warning, rvalue-reference to the temporary
94   for (const int &x : A) {}
95   // expected-warning@-1 {{binds to a temporary value produced by a range}}
96   // expected-note@-2 {{'int'}}
97   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
98   for (const int x : A) {}
99   // No warning, non-reference type indicates copy is made
100   for (int&& x : A) {}
101   // No warning, rvalue-reference to the temporary
102   //for (int &x : A) {}
103   // Binding error
104   for (int x : A) {}
105   // No warning, non-reference type indicates copy is made
106 
107   for (const double &&x : A) {}
108   // No warning, rvalue-reference to the temporary
109   for (const double &x : A) {}
110   // expected-warning@-1 {{binds to a temporary value produced by a range}}
111   // expected-note@-2 {{'double'}}
112   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:""
113   for (const double x : A) {}
114   // No warning, non-reference type indicates copy is made
115   for (double &&x : A) {}
116   // No warning, rvalue-reference to the temporary
117   //for (double &x : A) {}
118   // Binding error
119   for (double x : A) {}
120   // No warning, non-reference type indicates copy is made
121 
122   for (const Bar &&x : A) {}
123   // No warning, rvalue-reference to the temporary
124   for (const Bar &x : A) {}
125   // expected-warning@-1 {{binds to a temporary value produced by a range}}
126   // expected-note@-2 {{'Bar'}}
127   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
128   for (const Bar x : A) {}
129   // No warning, non-reference type indicates copy is made
130   for (Bar &&x : A) {}
131   // No warning, rvalue-reference to the temporary
132   //for (Bar &x : A) {}
133   // Binding error
134   for (Bar x : A) {}
135   // No warning, non-reference type indicates copy is made
136 }
137 
test2()138 void test2() {
139   Container<int&> B;
140 
141   //for (const int &&x : B) {}
142   // Binding error
143   for (const int &x : B) {}
144   // No warning, this reference is not a temporary
145   for (const int x : B) {}
146   // No warning on POD copy
147   //for (int &x : B) {}
148   // Binding error
149   for (int &x : B) {}
150   // No warning
151   for (int x : B) {}
152   // No warning
153 
154   for (const double &&x : B) {}
155   // expected-warning@-1 {{binds to a temporary constructed from}}
156   // expected-note-re@-2 {{'double'{{.*}}'const int &'}}
157   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:23}:""
158   for (const double &x : B) {}
159   // expected-warning@-1 {{binds to a temporary constructed from}}
160   // expected-note-re@-2 {{'double'{{.*}}'const int &'}}
161   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:""
162   for (const double x : B) {}
163   for (double &&x : B) {}
164   // expected-warning@-1 {{binds to a temporary constructed from}}
165   // expected-note-re@-2 {{'double'{{.*}}'const int &'}}
166   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:17}:""
167   //for (double &x : B) {}
168   // Binding error
169   for (double x : B) {}
170   // No warning
171 
172   for (const Bar &&x : B) {}
173   // expected-warning@-1 {{binds to a temporary constructed from}}
174   // expected-note@-2 {{'Bar'}}
175   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
176   for (const Bar &x : B) {}
177   // expected-warning@-1 {{binds to a temporary constructed from}}
178   // expected-note@-2 {{'Bar'}}
179   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
180   for (const Bar x : B) {}
181   for (Bar &&x : B) {}
182   // expected-warning@-1 {{binds to a temporary constructed from}}
183   // expected-note@-2 {{'Bar'}}
184   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
185   //for (Bar &x : B) {}
186   // Binding error
187   for (Bar x : B) {}
188   // No warning
189 }
190 
test3()191 void test3() {
192   Container<Bar> C;
193 
194   for (const Bar &&x : C) {}
195   // No warning, rvalue-reference to the temporary
196   for (const Bar &x : C) {}
197   // expected-warning@-1 {{binds to a temporary value produced by a range}}
198   // expected-note@-2 {{'Bar'}}
199   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
200   for (const Bar x : C) {}
201   // No warning, non-reference type indicates copy is made
202   for (Bar &&x : C) {}
203   // No warning, rvalue-reference to the temporary
204   //for (Bar &x : C) {}
205   // Binding error
206   for (Bar x : C) {}
207   // No warning, non-reference type indicates copy is made
208 
209   for (const int &&x : C) {}
210   // No warning, rvalue-reference to the temporary
211   for (const int &x : C) {}
212   // expected-warning@-1 {{binds to a temporary value produced by a range}}
213   // expected-note@-2 {{'int'}}
214   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
215   for (const int x : C) {}
216   // No warning, copy made
217   for (int &&x : C) {}
218   // No warning, rvalue-reference to the temporary
219   //for (int &x : C) {}
220   // Binding error
221   for (int x : C) {}
222   // No warning, copy made
223 }
224 
test4()225 void test4() {
226   Container<Bar&> D;
227 
228   //for (const Bar &&x : D) {}
229   // Binding error
230   for (const Bar &x : D) {}
231   // No warning, this reference is not a temporary
232   for (const Bar x : D) {}
233   // expected-warning@-1 {{creates a copy}}
234   // expected-note@-2 {{'const Bar &'}}
235   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&"
236   //for (Bar &&x : D) {}
237   // Binding error
238   for (Bar &x : D) {}
239   // No warning
240   for (Bar x : D) {}
241   // No warning
242 
243   for (const int &&x : D) {}
244   // expected-warning@-1 {{binds to a temporary constructed from}}
245   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
246   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
247   for (const int &x : D) {}
248   // expected-warning@-1 {{binds to a temporary constructed from}}
249   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
250   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
251   for (const int x : D) {}
252   // No warning
253   for (int &&x : D) {}
254   // expected-warning@-1 {{binds to a temporary constructed from}}
255   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
256   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
257   //for (int &x : D) {}
258   // Binding error
259   for (int x : D) {}
260   // No warning
261 }
262 
test5()263 void test5() {
264   Container<Foo> E;
265 
266   for (const Bar &&x : E) {}
267   // No warning, rvalue-reference to the temporary
268   for (const Bar &x : E) {}
269   // expected-warning@-1 {{binds to a temporary value produced by a range}}
270   // expected-note@-2 {{'Bar'}}
271   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
272   for (const Bar x : E) {}
273   // No warning, non-reference type indicates copy is made
274   for (Bar &&x : E) {}
275   // No warning, rvalue-reference to the temporary
276   //for (Bar &x : E) {}
277   // Binding error
278   for (Bar x : E) {}
279   // No warning, non-reference type indicates copy is made
280 }
281 
test6()282 void test6() {
283   Container<Foo&> F;
284 
285   for (const Bar &&x : F) {}
286   // expected-warning@-1 {{binds to a temporary constructed from}}
287   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
288   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
289   for (const Bar &x : F) {}
290   // expected-warning@-1 {{binds to a temporary constructed from}}
291   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
292   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
293   for (const Bar x : F) {}
294   // No warning.
295   for (Bar &&x : F) {}
296   // expected-warning@-1 {{binds to a temporary constructed from}}
297   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
298   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
299   //for (Bar &x : F) {}
300   // Binding error
301   for (Bar x : F) {}
302   // No warning
303 }
304 
test7()305 void test7() {
306   double G[2];
307 
308   //for (const double &&x : G) {}
309   // Binding error
310   for (const double &x : G) {}
311   // No warning
312   for (const double x : G) {}
313   // No warning on POD copy
314   //for (double &&x : G) {}
315   // Binding error
316   for (double &x : G) {}
317   // No warning
318   for (double x : G) {}
319   // No warning
320 
321   for (const int &&x : G) {}
322   // expected-warning@-1 {{binds to a temporary constructed from}}
323   // expected-note-re@-2 {{'int'{{.*}}'const double &'}}
324   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
325   for (const int &x : G) {}
326   // expected-warning@-1 {{binds to a temporary constructed from}}
327   // expected-note-re@-2 {{'int'{{.*}}'const double &'}}
328   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
329   for (const int x : G) {}
330   // No warning
331   for (int &&x : G) {}
332   // expected-warning@-1 {{binds to a temporary constructed from}}
333   // expected-note-re@-2 {{'int'{{.*}}'const double &'}}
334   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
335   //for (int &x : G) {}
336   // Binding error
337   for (int x : G) {}
338   // No warning
339 
340   for (const Bar &&x : G) {}
341   // expected-warning@-1 {{binds to a temporary constructed from}}
342   // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}}
343   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
344   for (const Bar &x : G) {}
345   // expected-warning@-1 {{binds to a temporary constructed from}}
346   // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}}
347   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
348   for (const Bar x : G) {}
349   // No warning
350   for (Bar &&x : G) {}
351   // expected-warning@-1 {{binds to a temporary constructed from}}
352   // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}}
353   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
354   //for (Bar &x : G) {}
355   // Binding error
356   for (Bar x : G) {}
357   // No warning
358 }
359 
test8()360 void test8() {
361   Foo H[2];
362 
363   //for (const Foo &&x : H) {}
364   // Binding error
365   for (const Foo &x : H) {}
366   // No warning
367   for (const Foo x : H) {}
368   // No warning on POD copy
369   //for (Foo &&x : H) {}
370   // Binding error
371   for (Foo &x : H) {}
372   // No warning
373   for (Foo x : H) {}
374   // No warning
375 
376   for (const Bar &&x : H) {}
377   // expected-warning@-1 {{binds to a temporary constructed from}}
378   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
379   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
380   for (const Bar &x : H) {}
381   // expected-warning@-1 {{binds to a temporary constructed from}}
382   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
383   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
384   for (const Bar x : H) {}
385   // No warning
386   for (Bar &&x: H) {}
387   // expected-warning@-1 {{binds to a temporary constructed from}}
388   // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}}
389   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
390   //for (Bar &x: H) {}
391   // Binding error
392   for (Bar x: H) {}
393   // No warning
394 }
395 
test9()396 void test9() {
397   Bar I[2] = {1,2};
398 
399   //for (const Bar &&x : I) {}
400   // Binding error
401   for (const Bar &x : I) {}
402   // No warning
403   for (const Bar x : I) {}
404   // expected-warning@-1 {{creates a copy}}
405   // expected-note@-2 {{'const Bar &'}}
406   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&"
407   //for (Bar &&x : I) {}
408   // Binding error
409   for (Bar &x : I) {}
410   // No warning
411   for (Bar x : I) {}
412   // No warning
413 
414   for (const int &&x : I) {}
415   // expected-warning@-1 {{binds to a temporary constructed from}}
416   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
417   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
418   for (const int &x : I) {}
419   // expected-warning@-1 {{binds to a temporary constructed from}}
420   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
421   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
422   for (const int x : I) {}
423   // No warning
424   for (int &&x : I) {}
425   // expected-warning@-1 {{binds to a temporary constructed from}}
426   // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}}
427   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""
428   //for (int &x : I) {}
429   // Binding error
430   for (int x : I) {}
431   // No warning
432 }
433 
test10()434 void test10() {
435   Container<Bar> C;
436 
437   for (const Bar &x : C) {}
438   // expected-warning@-1 {{binds to a temporary value produced by a range}}
439   // expected-note@-2 {{'Bar'}}
440   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
441 
442   for (const Bar& x : C) {}
443   // expected-warning@-1 {{binds to a temporary value produced by a range}}
444   // expected-note@-2 {{'Bar'}}
445   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:""
446 
447   for (const Bar & x : C) {}
448   // expected-warning@-1 {{binds to a temporary value produced by a range}}
449   // expected-note@-2 {{'Bar'}}
450   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
451 
452   for (const Bar&x : C) {}
453   // expected-warning@-1 {{binds to a temporary value produced by a range}}
454   // expected-note@-2 {{'Bar'}}
455   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" "
456 }
457 
458 template <class T>
test_template_function()459 void test_template_function() {
460   // In a template instantiation the diagnostics should not be emitted for
461   // loops with dependent types.
462   Container<Bar> C;
463   for (const Bar &x : C) {}
464   // expected-warning@-1 {{binds to a temporary value produced by a range}}
465   // expected-note@-2 {{'Bar'}}
466   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
467 
468   Container<T> Dependent;
469   for (const T &x : Dependent) {}
470 }
471 template void test_template_function<Bar>();
472 
473 template <class T>
474 struct test_template_struct {
static_membertest_template_struct475   static void static_member() {
476     Container<Bar> C;
477     for (const Bar &x : C) {}
478     // expected-warning@-1 {{binds to a temporary value produced by a range}}
479     // expected-note@-2 {{'Bar'}}
480     // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
481 
482     Container<T> Dependent;
483     for (const T &x : Dependent) {}
484   }
485 
membertest_template_struct486   void member() {
487     Container<Bar> C;
488     for (const Bar &x : C) {}
489     // expected-warning@-1 {{binds to a temporary value produced by a range}}
490     // expected-note@-2 {{'Bar'}}
491     // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
492 
493     Container<T> Dependent;
494     for (const T &x : Dependent) {}
495   }
496 };
497 template struct test_template_struct<Bar>;
498 
499 struct test_struct_with_templated_member {
membertest_struct_with_templated_member500   void member() {
501     Container<Bar> C;
502     for (const Bar &x : C) {}
503     // expected-warning@-1 {{binds to a temporary value produced by a range}}
504     // expected-note@-2 {{'Bar'}}
505     // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
506   }
507 
508   template <class T>
template_membertest_struct_with_templated_member509   void template_member() {
510     Container<Bar> C;
511     for (const Bar &x : C) {}
512     // expected-warning@-1 {{binds to a temporary value produced by a range}}
513     // expected-note@-2 {{'Bar'}}
514     // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
515 
516     Container<T> Dependent;
517     for (const T &x : Dependent) {}
518   }
519 };
520 template void test_struct_with_templated_member::template_member<Bar>();
521 
522 #define TEST_MACRO            \
523   void test_macro() {         \
524     Container<Bar> C;         \
525     for (const Bar &x : C) {} \
526   }
527 
528 TEST_MACRO
529