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