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