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 variable, 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 
test0()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 
test1()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 
test2()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 
test3()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 
test4()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 
test5()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 
test6()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 
test7()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 
test8()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 
test9()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 }
300