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
6 template <typename return_type
>
8 return_type
operator*();
10 bool operator!=(const Iterator
);
15 typedef Iterator
<T
> I
;
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
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.
47 // Conversions during tests:
69 Container
<int> int_non_ref_container
;
70 Container
<int&> int_container
;
71 Container
<Bar
&> bar_container
;
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}:""
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}:""
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}:"&"
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
101 // No warning, rvalue-reference to the temporary
102 //for (int &x : A) {}
105 // No warning, non-reference type indicates copy is made
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) {}
119 for (double x
: A
) {}
120 // No warning, non-reference type indicates copy is made
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
131 // No warning, rvalue-reference to the temporary
132 //for (Bar &x : A) {}
135 // No warning, non-reference type indicates copy is made
141 //for (const int &&x : B) {}
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) {}
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) {}
169 for (double x
: B
) {}
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
) {}
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) {}
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
203 // No warning, rvalue-reference to the temporary
204 //for (Bar &x : C) {}
207 // No warning, non-reference type indicates copy is made
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
218 // No warning, rvalue-reference to the temporary
219 //for (int &x : C) {}
222 // No warning, copy made
228 //for (const Bar &&x : D) {}
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) {}
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
) {}
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) {}
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
275 // No warning, rvalue-reference to the temporary
276 //for (Bar &x : E) {}
279 // No warning, non-reference type indicates copy is made
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
) {}
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) {}
308 //for (const double &&x : G) {}
310 for (const double &x
: G
) {}
312 for (const double x
: G
) {}
313 // No warning on POD copy
314 //for (double &&x : G) {}
316 for (double &x
: G
) {}
318 for (double x
: G
) {}
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
) {}
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) {}
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
) {}
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) {}
363 //for (const Foo &&x : H) {}
365 for (const Foo
&x
: H
) {}
367 for (const Foo x
: H
) {}
368 // No warning on POD copy
369 //for (Foo &&x : H) {}
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
) {}
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}:""
399 //for (const Bar &&x : I) {}
401 for (const Bar
&x
: I
) {}
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) {}
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
) {}
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) {}
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}:""
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}:""
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}:""
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}:" "
459 void test_template_function() {
460 // In a template instantiation the diagnostics should not be emitted for
461 // loops with dependent types.
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}:""
468 Container
<T
> Dependent
;
469 for (const T
&x
: Dependent
) {}
471 template void test_template_function
<Bar
>();
474 struct test_template_struct
{
475 static void static_member() {
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}:""
482 Container
<T
> Dependent
;
483 for (const T
&x
: Dependent
) {}
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}:""
493 Container
<T
> Dependent
;
494 for (const T
&x
: Dependent
) {}
497 template struct test_template_struct
<Bar
>;
499 struct test_struct_with_templated_member
{
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}:""
509 void template_member() {
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}:""
516 Container
<T
> Dependent
;
517 for (const T
&x
: Dependent
) {}
520 template void test_struct_with_templated_member::template_member
<Bar
>();
523 void test_macro() { \
525 for (const Bar &x : C) {} \