xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert
2*89a1d03eSRichard 
3*89a1d03eSRichard #include "structures.h"
4*89a1d03eSRichard 
5*89a1d03eSRichard namespace Dependency {
6*89a1d03eSRichard 
f()7*89a1d03eSRichard void f() {
8*89a1d03eSRichard   const int N = 6;
9*89a1d03eSRichard   const int M = 8;
10*89a1d03eSRichard   int Arr[N][M];
11*89a1d03eSRichard 
12*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
13*89a1d03eSRichard     int A = 0;
14*89a1d03eSRichard     int B = Arr[I][A];
15*89a1d03eSRichard   }
16*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
17*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Arr)
18*89a1d03eSRichard   // CHECK-FIXES-NEXT: int A = 0;
19*89a1d03eSRichard   // CHECK-FIXES-NEXT: int B = I[A];
20*89a1d03eSRichard 
21*89a1d03eSRichard   for (int J = 0; J < M; ++J) {
22*89a1d03eSRichard     int A = 0;
23*89a1d03eSRichard     int B = Arr[A][J];
24*89a1d03eSRichard   }
25*89a1d03eSRichard }
26*89a1d03eSRichard 
27*89a1d03eSRichard } // namespace Dependency
28*89a1d03eSRichard 
29*89a1d03eSRichard namespace NamingAlias {
30*89a1d03eSRichard 
31*89a1d03eSRichard const int N = 10;
32*89a1d03eSRichard 
33*89a1d03eSRichard Val Arr[N];
34*89a1d03eSRichard dependent<Val> V;
35*89a1d03eSRichard dependent<Val> *Pv;
36*89a1d03eSRichard Val &func(Val &);
37*89a1d03eSRichard void sideEffect(int);
38*89a1d03eSRichard 
aliasing()39*89a1d03eSRichard void aliasing() {
40*89a1d03eSRichard   // If the loop container is only used for a declaration of a temporary
41*89a1d03eSRichard   // variable to hold each element, we can name the new variable for the
42*89a1d03eSRichard   // converted range-based loop as the temporary variable's name.
43*89a1d03eSRichard 
44*89a1d03eSRichard   // In the following case, "T" is used as a temporary variable to hold each
45*89a1d03eSRichard   // element, and thus we consider the name "T" aliased to the loop.
46*89a1d03eSRichard   // The extra blank braces are left as a placeholder for after the variable
47*89a1d03eSRichard   // declaration is deleted.
48*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
49*89a1d03eSRichard     Val &T = Arr[I];
50*89a1d03eSRichard     {}
51*89a1d03eSRichard     int Y = T.X;
52*89a1d03eSRichard   }
53*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
54*89a1d03eSRichard   // CHECK-FIXES: for (auto & T : Arr)
55*89a1d03eSRichard   // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
56*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
57*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
58*89a1d03eSRichard 
59*89a1d03eSRichard   // The container was not only used to initialize a temporary loop variable for
60*89a1d03eSRichard   // the container's elements, so we do not alias the new loop variable.
61*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
62*89a1d03eSRichard     Val &T = Arr[I];
63*89a1d03eSRichard     int Y = T.X;
64*89a1d03eSRichard     int Z = Arr[I].X + T.X;
65*89a1d03eSRichard   }
66*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
67*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Arr)
68*89a1d03eSRichard   // CHECK-FIXES-NEXT: Val &T = I;
69*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
70*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Z = I.X + T.X;
71*89a1d03eSRichard 
72*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
73*89a1d03eSRichard     Val T = Arr[I];
74*89a1d03eSRichard     int Y = T.X;
75*89a1d03eSRichard     int Z = Arr[I].X + T.X;
76*89a1d03eSRichard   }
77*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
78*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Arr)
79*89a1d03eSRichard   // CHECK-FIXES-NEXT: Val T = I;
80*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
81*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Z = I.X + T.X;
82*89a1d03eSRichard 
83*89a1d03eSRichard   // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
84*89a1d03eSRichard   // which provide a subscript operator[].
85*89a1d03eSRichard   for (int I = 0; I < V.size(); ++I) {
86*89a1d03eSRichard     Val &T = V[I];
87*89a1d03eSRichard     {}
88*89a1d03eSRichard     int Y = T.X;
89*89a1d03eSRichard   }
90*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
91*89a1d03eSRichard   // CHECK-FIXES: for (auto & T : V)
92*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
93*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
94*89a1d03eSRichard 
95*89a1d03eSRichard   // The same with a call to at()
96*89a1d03eSRichard   for (int I = 0; I < Pv->size(); ++I) {
97*89a1d03eSRichard     Val &T = Pv->at(I);
98*89a1d03eSRichard     {}
99*89a1d03eSRichard     int Y = T.X;
100*89a1d03eSRichard   }
101*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
102*89a1d03eSRichard   // CHECK-FIXES: for (auto & T : *Pv)
103*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
104*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
105*89a1d03eSRichard 
106*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
107*89a1d03eSRichard     Val &T = func(Arr[I]);
108*89a1d03eSRichard     int Y = T.X;
109*89a1d03eSRichard   }
110*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
111*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Arr)
112*89a1d03eSRichard   // CHECK-FIXES-NEXT: Val &T = func(I);
113*89a1d03eSRichard   // CHECK-FIXES-NEXT: int Y = T.X;
114*89a1d03eSRichard 
115*89a1d03eSRichard   int IntArr[N];
116*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
117*89a1d03eSRichard     if (int Alias = IntArr[I]) {
118*89a1d03eSRichard       sideEffect(Alias);
119*89a1d03eSRichard     }
120*89a1d03eSRichard   }
121*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
122*89a1d03eSRichard   // CHECK-FIXES: for (int Alias : IntArr)
123*89a1d03eSRichard   // CHECK-FIXES-NEXT: if (Alias)
124*89a1d03eSRichard 
125*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
126*89a1d03eSRichard     while (int Alias = IntArr[I]) {
127*89a1d03eSRichard       sideEffect(Alias);
128*89a1d03eSRichard     }
129*89a1d03eSRichard   }
130*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
131*89a1d03eSRichard   // CHECK-FIXES: for (int Alias : IntArr)
132*89a1d03eSRichard   // CHECK-FIXES-NEXT: while (Alias)
133*89a1d03eSRichard 
134*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
135*89a1d03eSRichard     switch (int Alias = IntArr[I]) {
136*89a1d03eSRichard     default:
137*89a1d03eSRichard       sideEffect(Alias);
138*89a1d03eSRichard     }
139*89a1d03eSRichard   }
140*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
141*89a1d03eSRichard   // CHECK-FIXES: for (int Alias : IntArr)
142*89a1d03eSRichard   // CHECK-FIXES-NEXT: switch (Alias)
143*89a1d03eSRichard 
144*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
145*89a1d03eSRichard     for (int Alias = IntArr[I]; Alias < N; ++Alias) {
146*89a1d03eSRichard       sideEffect(Alias);
147*89a1d03eSRichard     }
148*89a1d03eSRichard   }
149*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
150*89a1d03eSRichard   // CHECK-FIXES: for (int Alias : IntArr)
151*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias)
152*89a1d03eSRichard 
153*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
154*89a1d03eSRichard     for (unsigned J = 0; int Alias = IntArr[I]; ++J) {
155*89a1d03eSRichard       sideEffect(Alias);
156*89a1d03eSRichard     }
157*89a1d03eSRichard   }
158*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
159*89a1d03eSRichard   // CHECK-FIXES: for (int Alias : IntArr)
160*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
161*89a1d03eSRichard 
162*89a1d03eSRichard   struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
163*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
164*89a1d03eSRichard     IntRef Int(IntArr[I]);
165*89a1d03eSRichard   }
166*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
167*89a1d03eSRichard   // CHECK-FIXES: for (int I : IntArr)
168*89a1d03eSRichard   // CHECK-FIXES-NEXT: IntRef Int(I);
169*89a1d03eSRichard 
170*89a1d03eSRichard   int *PtrArr[N];
171*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
172*89a1d03eSRichard     const int* const P = PtrArr[I];
173*89a1d03eSRichard     printf("%d\n", *P);
174*89a1d03eSRichard   }
175*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
176*89a1d03eSRichard   // CHECK-FIXES: for (auto P : PtrArr)
177*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", *P);
178*89a1d03eSRichard 
179*89a1d03eSRichard   IntRef Refs[N];
180*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
181*89a1d03eSRichard     int *P = Refs[I];
182*89a1d03eSRichard     printf("%d\n", *P);
183*89a1d03eSRichard   }
184*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
185*89a1d03eSRichard   // CHECK-FIXES: for (auto & Ref : Refs)
186*89a1d03eSRichard   // CHECK-FIXES-NEXT: int *P = Ref;
187*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", *P);
188*89a1d03eSRichard 
189*89a1d03eSRichard   // Ensure that removing the alias doesn't leave empty lines behind.
190*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
191*89a1d03eSRichard     auto &X = IntArr[I];
192*89a1d03eSRichard     X = 0;
193*89a1d03eSRichard   }
194*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
195*89a1d03eSRichard   // CHECK-FIXES: for (int & X : IntArr) {
196*89a1d03eSRichard   // CHECK-FIXES-NEXT: {{^    X = 0;$}}
197*89a1d03eSRichard   // CHECK-FIXES-NEXT: {{^  }$}}
198*89a1d03eSRichard }
199*89a1d03eSRichard 
refs_and_vals()200*89a1d03eSRichard void refs_and_vals() {
201*89a1d03eSRichard   // The following tests check that the transform correctly preserves the
202*89a1d03eSRichard   // reference or value qualifiers of the aliased variable. That is, if the
203*89a1d03eSRichard   // variable was declared as a value, the loop variable will be declared as a
204*89a1d03eSRichard   // value and vice versa for references.
205*89a1d03eSRichard 
206*89a1d03eSRichard   S Ss;
207*89a1d03eSRichard   const S S_const = Ss;
208*89a1d03eSRichard 
209*89a1d03eSRichard   for (S::const_iterator It = S_const.begin(); It != S_const.end(); ++It) {
210*89a1d03eSRichard     MutableVal Alias = *It;
211*89a1d03eSRichard     {}
212*89a1d03eSRichard     Alias.X = 0;
213*89a1d03eSRichard   }
214*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
215*89a1d03eSRichard   // CHECK-FIXES: for (auto Alias : S_const)
216*89a1d03eSRichard   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
217*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
218*89a1d03eSRichard   // CHECK-FIXES-NEXT: Alias.X = 0;
219*89a1d03eSRichard 
220*89a1d03eSRichard   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
221*89a1d03eSRichard     MutableVal Alias = *It;
222*89a1d03eSRichard     {}
223*89a1d03eSRichard     Alias.X = 0;
224*89a1d03eSRichard   }
225*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
226*89a1d03eSRichard   // CHECK-FIXES: for (auto Alias : Ss)
227*89a1d03eSRichard   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
228*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
229*89a1d03eSRichard   // CHECK-FIXES-NEXT: Alias.X = 0;
230*89a1d03eSRichard 
231*89a1d03eSRichard   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
232*89a1d03eSRichard     MutableVal &Alias = *It;
233*89a1d03eSRichard     {}
234*89a1d03eSRichard     Alias.X = 0;
235*89a1d03eSRichard   }
236*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
237*89a1d03eSRichard   // CHECK-FIXES: for (auto & Alias : Ss)
238*89a1d03eSRichard   // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
239*89a1d03eSRichard   // CHECK-FIXES-NEXT: {}
240*89a1d03eSRichard   // CHECK-FIXES-NEXT: Alias.X = 0;
241*89a1d03eSRichard 
242*89a1d03eSRichard   dependent<int> Dep, Other;
243*89a1d03eSRichard   for (dependent<int>::iterator It = Dep.begin(), E = Dep.end(); It != E; ++It) {
244*89a1d03eSRichard     printf("%d\n", *It);
245*89a1d03eSRichard     const int& Idx = Other[0];
246*89a1d03eSRichard     unsigned Othersize = Other.size();
247*89a1d03eSRichard   }
248*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
249*89a1d03eSRichard   // CHECK-FIXES: for (int & It : Dep)
250*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", It);
251*89a1d03eSRichard   // CHECK-FIXES-NEXT: const int& Idx = Other[0];
252*89a1d03eSRichard   // CHECK-FIXES-NEXT: unsigned Othersize = Other.size();
253*89a1d03eSRichard 
254*89a1d03eSRichard   for (int i = 0; i <  Other.size(); ++i) {
255*89a1d03eSRichard     Other.at(i);
256*89a1d03eSRichard   }
257*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
258*89a1d03eSRichard   // CHECK-FIXES: for (int & i : Other)
259*89a1d03eSRichard   // CHECK-FIXES: i;
260*89a1d03eSRichard 
261*89a1d03eSRichard   for (int I = 0, E = Dep.size(); I != E; ++I) {
262*89a1d03eSRichard     int Idx = Other.at(I);
263*89a1d03eSRichard     Other.at(I, I);  // Should not trigger assert failure.
264*89a1d03eSRichard   }
265*89a1d03eSRichard }
266*89a1d03eSRichard 
267*89a1d03eSRichard struct MemberNaming {
268*89a1d03eSRichard   const static int N = 10;
269*89a1d03eSRichard   int Ints[N], Ints_[N];
270*89a1d03eSRichard   dependent<int> DInts;
loopsNamingAlias::MemberNaming271*89a1d03eSRichard   void loops() {
272*89a1d03eSRichard     for (int I = 0; I < N; ++I) {
273*89a1d03eSRichard       printf("%d\n", Ints[I]);
274*89a1d03eSRichard     }
275*89a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
276*89a1d03eSRichard     // CHECK-FIXES: for (int Int : Ints)
277*89a1d03eSRichard     // CHECK-FIXES-NEXT: printf("%d\n", Int);
278*89a1d03eSRichard 
279*89a1d03eSRichard     for (int I = 0; I < N; ++I) {
280*89a1d03eSRichard       printf("%d\n", Ints_[I]);
281*89a1d03eSRichard     }
282*89a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
283*89a1d03eSRichard     // CHECK-FIXES: for (int Int : Ints_)
284*89a1d03eSRichard     // CHECK-FIXES-NEXT: printf("%d\n", Int);
285*89a1d03eSRichard 
286*89a1d03eSRichard     for (int I = 0; I < DInts.size(); ++I) {
287*89a1d03eSRichard       printf("%d\n", DInts[I]);
288*89a1d03eSRichard     }
289*89a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
290*89a1d03eSRichard     // CHECK-FIXES: for (int DInt : DInts)
291*89a1d03eSRichard     // CHECK-FIXES-NEXT: printf("%d\n", DInt);
292*89a1d03eSRichard   }
293*89a1d03eSRichard 
294*89a1d03eSRichard   void outOfLine();
295*89a1d03eSRichard };
outOfLine()296*89a1d03eSRichard void MemberNaming::outOfLine() {
297*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
298*89a1d03eSRichard     printf("%d\n", Ints[I]);
299*89a1d03eSRichard   }
300*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
301*89a1d03eSRichard   // CHECK-FIXES: for (int Int : Ints)
302*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", Int);
303*89a1d03eSRichard 
304*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
305*89a1d03eSRichard     printf("%d\n", Ints_[I]);
306*89a1d03eSRichard   }
307*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
308*89a1d03eSRichard   // CHECK-FIXES: for (int Int : Ints_)
309*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", Int);
310*89a1d03eSRichard }
311*89a1d03eSRichard 
312*89a1d03eSRichard } // namespace NamingAlias
313*89a1d03eSRichard 
314*89a1d03eSRichard namespace NamingConlict {
315*89a1d03eSRichard 
316*89a1d03eSRichard #define MAX(a, b) (a > b) ? a : b
317*89a1d03eSRichard #define DEF 5
318*89a1d03eSRichard 
319*89a1d03eSRichard const int N = 10;
320*89a1d03eSRichard int Nums[N];
321*89a1d03eSRichard int Sum = 0;
322*89a1d03eSRichard 
323*89a1d03eSRichard namespace ns {
324*89a1d03eSRichard struct St {
325*89a1d03eSRichard   int X;
326*89a1d03eSRichard };
327*89a1d03eSRichard }
328*89a1d03eSRichard 
sameNames()329*89a1d03eSRichard void sameNames() {
330*89a1d03eSRichard   int Num = 0;
331*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
332*89a1d03eSRichard     printf("Fibonacci number is %d\n", Nums[I]);
333*89a1d03eSRichard     Sum += Nums[I] + 2 + Num;
334*89a1d03eSRichard     (void)Nums[I];
335*89a1d03eSRichard   }
336*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
337*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Nums)
338*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
339*89a1d03eSRichard   // CHECK-FIXES-NEXT: Sum += I + 2 + Num;
340*89a1d03eSRichard   // CHECK-FIXES-NEXT: (void)I;
341*89a1d03eSRichard 
342*89a1d03eSRichard   int Elem = 0;
343*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
344*89a1d03eSRichard     printf("Fibonacci number is %d\n", Nums[I]);
345*89a1d03eSRichard     Sum += Nums[I] + 2 + Num + Elem;
346*89a1d03eSRichard     (void)Nums[I];
347*89a1d03eSRichard   }
348*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
349*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Nums)
350*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
351*89a1d03eSRichard   // CHECK-FIXES-NEXT: Sum += I + 2 + Num + Elem;
352*89a1d03eSRichard   // CHECK-FIXES-NEXT: (void)I;
353*89a1d03eSRichard }
354*89a1d03eSRichard 
oldIndexConflict()355*89a1d03eSRichard void oldIndexConflict() {
356*89a1d03eSRichard   for (int Num = 0; Num < N; ++Num) {
357*89a1d03eSRichard     printf("Num: %d\n", Nums[Num]);
358*89a1d03eSRichard   }
359*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
360*89a1d03eSRichard   // CHECK-FIXES: for (int Num : Nums)
361*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
362*89a1d03eSRichard 
363*89a1d03eSRichard   S Things;
364*89a1d03eSRichard   for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; ++Thing) {
365*89a1d03eSRichard     printf("Thing: %d %d\n", Thing->X, (*Thing).X);
366*89a1d03eSRichard   }
367*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
368*89a1d03eSRichard   // CHECK-FIXES: for (auto & Thing : Things)
369*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
370*89a1d03eSRichard }
371*89a1d03eSRichard 
macroConflict()372*89a1d03eSRichard void macroConflict() {
373*89a1d03eSRichard   S MAXs;
374*89a1d03eSRichard   for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
375*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
376*89a1d03eSRichard     printf("Max of 3 and 5: %d\n", MAX(3, 5));
377*89a1d03eSRichard   }
378*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
379*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : MAXs)
380*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
381*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
382*89a1d03eSRichard 
383*89a1d03eSRichard   for (S::const_iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
384*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
385*89a1d03eSRichard     printf("Max of 3 and 5: %d\n", MAX(3, 5));
386*89a1d03eSRichard   }
387*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
388*89a1d03eSRichard   // CHECK-FIXES: for (auto It : MAXs)
389*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
390*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
391*89a1d03eSRichard 
392*89a1d03eSRichard   T DEFs;
393*89a1d03eSRichard   for (T::iterator It = DEFs.begin(), E = DEFs.end(); It != E; ++It) {
394*89a1d03eSRichard     if (*It == DEF) {
395*89a1d03eSRichard       printf("I found %d\n", *It);
396*89a1d03eSRichard     }
397*89a1d03eSRichard   }
398*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
399*89a1d03eSRichard   // CHECK-FIXES: for (int & It : DEFs)
400*89a1d03eSRichard   // CHECK-FIXES-NEXT: if (It == DEF)
401*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("I found %d\n", It);
402*89a1d03eSRichard }
403*89a1d03eSRichard 
keywordConflict()404*89a1d03eSRichard void keywordConflict() {
405*89a1d03eSRichard   T ints;
406*89a1d03eSRichard   for (T::iterator It = ints.begin(), E = ints.end(); It != E; ++It) {
407*89a1d03eSRichard     *It = 5;
408*89a1d03eSRichard   }
409*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
410*89a1d03eSRichard   // CHECK-FIXES: for (int & It : ints)
411*89a1d03eSRichard   // CHECK-FIXES-NEXT: It = 5;
412*89a1d03eSRichard 
413*89a1d03eSRichard   U __FUNCTION__s;
414*89a1d03eSRichard   for (U::iterator It = __FUNCTION__s.begin(), E = __FUNCTION__s.end();
415*89a1d03eSRichard        It != E; ++It) {
416*89a1d03eSRichard     int __FUNCTION__s_It = (*It).X + 2;
417*89a1d03eSRichard   }
418*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
419*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : __FUNCTION__s)
420*89a1d03eSRichard   // CHECK-FIXES-NEXT: int __FUNCTION__s_It = It.X + 2;
421*89a1d03eSRichard }
422*89a1d03eSRichard 
typeConflict()423*89a1d03eSRichard void typeConflict() {
424*89a1d03eSRichard   T Vals;
425*89a1d03eSRichard   // Using the name "Val", although it is the name of an existing struct, is
426*89a1d03eSRichard   // safe in this loop since it will only exist within this scope.
427*89a1d03eSRichard   for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It)
428*89a1d03eSRichard     (void) *It;
429*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
430*89a1d03eSRichard   // CHECK-FIXES: for (int & Val : Vals)
431*89a1d03eSRichard 
432*89a1d03eSRichard   // We cannot use the name "Val" in this loop since there is a reference to
433*89a1d03eSRichard   // it in the body of the loop.
434*89a1d03eSRichard   for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It) {
435*89a1d03eSRichard     *It = sizeof(Val);
436*89a1d03eSRichard   }
437*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
438*89a1d03eSRichard   // CHECK-FIXES: for (int & It : Vals)
439*89a1d03eSRichard   // CHECK-FIXES-NEXT: It = sizeof(Val);
440*89a1d03eSRichard 
441*89a1d03eSRichard   typedef struct Val TD;
442*89a1d03eSRichard   U TDs;
443*89a1d03eSRichard   // Naming the variable "TD" within this loop is safe because the typedef
444*89a1d03eSRichard   // was never used within the loop.
445*89a1d03eSRichard   for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It)
446*89a1d03eSRichard     (void) *It;
447*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
448*89a1d03eSRichard   // CHECK-FIXES: for (auto & TD : TDs)
449*89a1d03eSRichard 
450*89a1d03eSRichard   // "TD" cannot be used in this loop since the typedef is being used.
451*89a1d03eSRichard   for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It) {
452*89a1d03eSRichard     TD V;
453*89a1d03eSRichard     V.X = 5;
454*89a1d03eSRichard     (void) *It;
455*89a1d03eSRichard   }
456*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
457*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : TDs)
458*89a1d03eSRichard   // CHECK-FIXES-NEXT: TD V;
459*89a1d03eSRichard   // CHECK-FIXES-NEXT: V.X = 5;
460*89a1d03eSRichard 
461*89a1d03eSRichard   using ns::St;
462*89a1d03eSRichard   T Sts;
463*89a1d03eSRichard   for (T::iterator It = Sts.begin(), E = Sts.end(); It != E; ++It) {
464*89a1d03eSRichard     *It = sizeof(St);
465*89a1d03eSRichard   }
466*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
467*89a1d03eSRichard   // CHECK-FIXES: for (int & It : Sts)
468*89a1d03eSRichard   // CHECK-FIXES-NEXT: It = sizeof(St);
469*89a1d03eSRichard }
470*89a1d03eSRichard 
471*89a1d03eSRichard } // namespace NamingConflict
472*89a1d03eSRichard 
473*89a1d03eSRichard namespace FreeBeginEnd {
474*89a1d03eSRichard 
475*89a1d03eSRichard // FIXME: Loop Convert should detect free begin()/end() functions.
476*89a1d03eSRichard 
477*89a1d03eSRichard struct MyArray {
478*89a1d03eSRichard   unsigned size();
479*89a1d03eSRichard };
480*89a1d03eSRichard 
481*89a1d03eSRichard template <typename T>
482*89a1d03eSRichard struct MyContainer {
483*89a1d03eSRichard };
484*89a1d03eSRichard 
485*89a1d03eSRichard int *begin(const MyArray &Arr);
486*89a1d03eSRichard int *end(const MyArray &Arr);
487*89a1d03eSRichard 
488*89a1d03eSRichard template <typename T>
489*89a1d03eSRichard T *begin(const MyContainer<T> &C);
490*89a1d03eSRichard template <typename T>
491*89a1d03eSRichard T *end(const MyContainer<T> &C);
492*89a1d03eSRichard 
493*89a1d03eSRichard // The Loop Convert Transform doesn't detect free functions begin()/end() and
494*89a1d03eSRichard // so fails to transform these cases which it should.
f()495*89a1d03eSRichard void f() {
496*89a1d03eSRichard   MyArray Arr;
497*89a1d03eSRichard   for (unsigned I = 0, E = Arr.size(); I < E; ++I) {
498*89a1d03eSRichard   }
499*89a1d03eSRichard 
500*89a1d03eSRichard   MyContainer<int> C;
501*89a1d03eSRichard   for (int *I = begin(C), *E = end(C); I != E; ++I) {
502*89a1d03eSRichard   }
503*89a1d03eSRichard }
504*89a1d03eSRichard 
505*89a1d03eSRichard } // namespace FreeBeginEnd
506*89a1d03eSRichard 
507*89a1d03eSRichard namespace Nesting {
508*89a1d03eSRichard 
509*89a1d03eSRichard void g(S::iterator It);
510*89a1d03eSRichard void const_g(S::const_iterator It);
511*89a1d03eSRichard class Foo {
512*89a1d03eSRichard  public:
513*89a1d03eSRichard   void g(S::iterator It);
514*89a1d03eSRichard   void const_g(S::const_iterator It);
515*89a1d03eSRichard };
516*89a1d03eSRichard 
f()517*89a1d03eSRichard void f() {
518*89a1d03eSRichard   const int N = 10;
519*89a1d03eSRichard   const int M = 15;
520*89a1d03eSRichard   Val Arr[N];
521*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
522*89a1d03eSRichard     for (int J = 0; J < N; ++J) {
523*89a1d03eSRichard       int K = Arr[I].X + Arr[J].X;
524*89a1d03eSRichard       // The repeat is there to allow FileCheck to make sure the two variable
525*89a1d03eSRichard       // names aren't the same.
526*89a1d03eSRichard       int L = Arr[I].X + Arr[J].X;
527*89a1d03eSRichard     }
528*89a1d03eSRichard   }
529*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead
530*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead
531*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Arr)
532*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (auto & J : Arr)
533*89a1d03eSRichard   // CHECK-FIXES-NEXT: int K = I.X + J.X;
534*89a1d03eSRichard   // CHECK-FIXES-NOT: int L = I.X + I.X;
535*89a1d03eSRichard 
536*89a1d03eSRichard   // The inner loop is also convertible, but doesn't need to be converted
537*89a1d03eSRichard   // immediately. FIXME: update this test when that changes.
538*89a1d03eSRichard   Val Nest[N][M];
539*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
540*89a1d03eSRichard     for (int J = 0; J < M; ++J) {
541*89a1d03eSRichard       printf("Got item %d", Nest[I][J].X);
542*89a1d03eSRichard     }
543*89a1d03eSRichard   }
544*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
545*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Nest)
546*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J)
547*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
548*89a1d03eSRichard 
549*89a1d03eSRichard   // Note that the order of M and N are switched for this test.
550*89a1d03eSRichard   for (int J = 0; J < M; ++J) {
551*89a1d03eSRichard     for (int I = 0; I < N; ++I) {
552*89a1d03eSRichard       printf("Got item %d", Nest[I][J].X);
553*89a1d03eSRichard     }
554*89a1d03eSRichard   }
555*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
556*89a1d03eSRichard   // CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[I])
557*89a1d03eSRichard   // CHECK-FIXES: for (int J = 0; J < M; ++J)
558*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (auto & I : Nest)
559*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
560*89a1d03eSRichard 
561*89a1d03eSRichard   // The inner loop is also convertible.
562*89a1d03eSRichard   Nested<T> NestT;
563*89a1d03eSRichard   for (Nested<T>::iterator I = NestT.begin(), E = NestT.end(); I != E; ++I) {
564*89a1d03eSRichard     for (T::iterator TI = (*I).begin(), TE = (*I).end(); TI != TE; ++TI) {
565*89a1d03eSRichard       printf("%d", *TI);
566*89a1d03eSRichard     }
567*89a1d03eSRichard   }
568*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
569*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : NestT)
570*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI)
571*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d", *TI);
572*89a1d03eSRichard 
573*89a1d03eSRichard   // The inner loop is also convertible.
574*89a1d03eSRichard   Nested<S> NestS;
575*89a1d03eSRichard   for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
576*89a1d03eSRichard     for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) {
577*89a1d03eSRichard       printf("%d", *SI);
578*89a1d03eSRichard     }
579*89a1d03eSRichard   }
580*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
581*89a1d03eSRichard   // CHECK-FIXES: for (auto I : NestS)
582*89a1d03eSRichard   // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI)
583*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d", *SI);
584*89a1d03eSRichard 
585*89a1d03eSRichard   for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
586*89a1d03eSRichard     const S &Ss = *I;
587*89a1d03eSRichard     for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
588*89a1d03eSRichard       printf("%d", *SI);
589*89a1d03eSRichard       const_g(SI);
590*89a1d03eSRichard     }
591*89a1d03eSRichard   }
592*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
593*89a1d03eSRichard   // CHECK-FIXES: for (auto Ss : NestS)
594*89a1d03eSRichard 
595*89a1d03eSRichard   for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
596*89a1d03eSRichard     S &Ss = *I;
597*89a1d03eSRichard     for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
598*89a1d03eSRichard       printf("%d", *SI);
599*89a1d03eSRichard       g(SI);
600*89a1d03eSRichard     }
601*89a1d03eSRichard   }
602*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
603*89a1d03eSRichard   // CHECK-FIXES: for (auto & Ss : NestS)
604*89a1d03eSRichard 
605*89a1d03eSRichard   Foo foo;
606*89a1d03eSRichard   for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
607*89a1d03eSRichard     const S &Ss = *I;
608*89a1d03eSRichard     for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
609*89a1d03eSRichard       printf("%d", *SI);
610*89a1d03eSRichard       foo.const_g(SI);
611*89a1d03eSRichard     }
612*89a1d03eSRichard   }
613*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
614*89a1d03eSRichard   // CHECK-FIXES: for (auto Ss : NestS)
615*89a1d03eSRichard 
616*89a1d03eSRichard   for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
617*89a1d03eSRichard     S &Ss = *I;
618*89a1d03eSRichard     for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
619*89a1d03eSRichard       printf("%d", *SI);
620*89a1d03eSRichard       foo.g(SI);
621*89a1d03eSRichard     }
622*89a1d03eSRichard   }
623*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
624*89a1d03eSRichard   // CHECK-FIXES: for (auto & Ss : NestS)
625*89a1d03eSRichard 
626*89a1d03eSRichard }
627*89a1d03eSRichard 
628*89a1d03eSRichard } // namespace Nesting
629*89a1d03eSRichard 
630*89a1d03eSRichard namespace SingleIterator {
631*89a1d03eSRichard 
complexContainer()632*89a1d03eSRichard void complexContainer() {
633*89a1d03eSRichard   X Exes[5];
634*89a1d03eSRichard   int Index = 0;
635*89a1d03eSRichard 
636*89a1d03eSRichard   for (S::iterator I = Exes[Index].getS().begin(), E = Exes[Index].getS().end(); I != E; ++I) {
637*89a1d03eSRichard     MutableVal K = *I;
638*89a1d03eSRichard     MutableVal J = *I;
639*89a1d03eSRichard   }
640*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
641*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Exes[Index].getS())
642*89a1d03eSRichard   // CHECK-FIXES-NEXT: MutableVal K = I;
643*89a1d03eSRichard   // CHECK-FIXES-NEXT: MutableVal J = I;
644*89a1d03eSRichard }
645*89a1d03eSRichard 
f()646*89a1d03eSRichard void f() {
647*89a1d03eSRichard   /// begin()/end() - based for loops here:
648*89a1d03eSRichard   T Tt;
649*89a1d03eSRichard   for (T::iterator It = Tt.begin(); It != Tt.end(); ++It) {
650*89a1d03eSRichard     printf("I found %d\n", *It);
651*89a1d03eSRichard   }
652*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
653*89a1d03eSRichard   // CHECK-FIXES: for (int & It : Tt)
654*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("I found %d\n", It);
655*89a1d03eSRichard 
656*89a1d03eSRichard   T *Pt;
657*89a1d03eSRichard   for (T::iterator It = Pt->begin(); It != Pt->end(); ++It) {
658*89a1d03eSRichard     printf("I found %d\n", *It);
659*89a1d03eSRichard   }
660*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
661*89a1d03eSRichard   // CHECK-FIXES: for (int & It : *Pt)
662*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("I found %d\n", It);
663*89a1d03eSRichard 
664*89a1d03eSRichard   S Ss;
665*89a1d03eSRichard   for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
666*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
667*89a1d03eSRichard   }
668*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
669*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Ss)
670*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
671*89a1d03eSRichard 
672*89a1d03eSRichard   S *Ps;
673*89a1d03eSRichard   for (S::iterator It = Ps->begin(); It != Ps->end(); ++It) {
674*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
675*89a1d03eSRichard   }
676*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
677*89a1d03eSRichard   // CHECK-FIXES: for (auto & P : *Ps)
678*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
679*89a1d03eSRichard 
680*89a1d03eSRichard   for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
681*89a1d03eSRichard     printf("s has value %d\n", It->X);
682*89a1d03eSRichard   }
683*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
684*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Ss)
685*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
686*89a1d03eSRichard 
687*89a1d03eSRichard   for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
688*89a1d03eSRichard     It->X = 3;
689*89a1d03eSRichard   }
690*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
691*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Ss)
692*89a1d03eSRichard   // CHECK-FIXES-NEXT: It.X = 3;
693*89a1d03eSRichard 
694*89a1d03eSRichard   for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
695*89a1d03eSRichard     (*It).X = 3;
696*89a1d03eSRichard   }
697*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
698*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Ss)
699*89a1d03eSRichard   // CHECK-FIXES-NEXT: It.X = 3;
700*89a1d03eSRichard 
701*89a1d03eSRichard   for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
702*89a1d03eSRichard     It->nonConstFun(4, 5);
703*89a1d03eSRichard   }
704*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
705*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Ss)
706*89a1d03eSRichard   // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
707*89a1d03eSRichard 
708*89a1d03eSRichard   U Uu;
709*89a1d03eSRichard   for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
710*89a1d03eSRichard     printf("s has value %d\n", It->X);
711*89a1d03eSRichard   }
712*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
713*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Uu)
714*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
715*89a1d03eSRichard 
716*89a1d03eSRichard   for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
717*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
718*89a1d03eSRichard   }
719*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
720*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : Uu)
721*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
722*89a1d03eSRichard 
723*89a1d03eSRichard   U::iterator A;
724*89a1d03eSRichard   for (U::iterator I = Uu.begin(); I != Uu.end(); ++I)
725*89a1d03eSRichard     int K = A->X + I->X;
726*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
727*89a1d03eSRichard   // CHECK-FIXES: for (auto & I : Uu)
728*89a1d03eSRichard   // CHECK-FIXES-NEXT: int K = A->X + I.X;
729*89a1d03eSRichard 
730*89a1d03eSRichard   dependent<int> V;
731*89a1d03eSRichard   for (dependent<int>::iterator It = V.begin();
732*89a1d03eSRichard        It != V.end(); ++It) {
733*89a1d03eSRichard     printf("Fibonacci number is %d\n", *It);
734*89a1d03eSRichard   }
735*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
736*89a1d03eSRichard   // CHECK-FIXES: for (int & It : V)
737*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
738*89a1d03eSRichard 
739*89a1d03eSRichard   for (dependent<int>::iterator It(V.begin());
740*89a1d03eSRichard        It != V.end(); ++It) {
741*89a1d03eSRichard     printf("Fibonacci number is %d\n", *It);
742*89a1d03eSRichard   }
743*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
744*89a1d03eSRichard   // CHECK-FIXES: for (int & It : V)
745*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
746*89a1d03eSRichard 
747*89a1d03eSRichard   doublyDependent<int, int> intmap;
748*89a1d03eSRichard   for (doublyDependent<int, int>::iterator It = intmap.begin();
749*89a1d03eSRichard        It != intmap.end(); ++It) {
750*89a1d03eSRichard     printf("intmap[%d] = %d", It->first, It->second);
751*89a1d03eSRichard   }
752*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
753*89a1d03eSRichard   // CHECK-FIXES: for (auto & It : intmap)
754*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second);
755*89a1d03eSRichard }
756*89a1d03eSRichard 
different_type()757*89a1d03eSRichard void different_type() {
758*89a1d03eSRichard   // Tests to verify the proper use of auto where the init variable type and the
759*89a1d03eSRichard   // initializer type differ or are mostly the same except for const qualifiers.
760*89a1d03eSRichard 
761*89a1d03eSRichard   // Ss.begin() returns a type 'iterator' which is just a non-const pointer and
762*89a1d03eSRichard   // differs from const_iterator only on the const qualification.
763*89a1d03eSRichard   S Ss;
764*89a1d03eSRichard   for (S::const_iterator It = Ss.begin(); It != Ss.end(); ++It) {
765*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
766*89a1d03eSRichard   }
767*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
768*89a1d03eSRichard   // CHECK-FIXES: for (auto It : Ss)
769*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
770*89a1d03eSRichard 
771*89a1d03eSRichard   S *Ps;
772*89a1d03eSRichard   for (S::const_iterator It = Ps->begin(); It != Ps->end(); ++It) {
773*89a1d03eSRichard     printf("s has value %d\n", (*It).X);
774*89a1d03eSRichard   }
775*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
776*89a1d03eSRichard   // CHECK-FIXES: for (auto P : *Ps)
777*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
778*89a1d03eSRichard 
779*89a1d03eSRichard   dependent<int> V;
780*89a1d03eSRichard   for (dependent<int>::const_iterator It = V.begin(); It != V.end(); ++It) {
781*89a1d03eSRichard     printf("Fibonacci number is %d\n", *It);
782*89a1d03eSRichard   }
783*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
784*89a1d03eSRichard   // CHECK-FIXES: for (int It : V)
785*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
786*89a1d03eSRichard 
787*89a1d03eSRichard   for (dependent<int>::const_iterator It(V.begin()); It != V.end(); ++It) {
788*89a1d03eSRichard     printf("Fibonacci number is %d\n", *It);
789*89a1d03eSRichard   }
790*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
791*89a1d03eSRichard   // CHECK-FIXES: for (int It : V)
792*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
793*89a1d03eSRichard }
794*89a1d03eSRichard 
795*89a1d03eSRichard } // namespace SingleIterator
796*89a1d03eSRichard 
797*89a1d03eSRichard 
798*89a1d03eSRichard namespace Macros {
799*89a1d03eSRichard 
800*89a1d03eSRichard #define TWO_PARAM(x, y) if (x == y) {}
801*89a1d03eSRichard #define THREE_PARAM(x, y, z) if (x == y) {z;}
802*89a1d03eSRichard 
803*89a1d03eSRichard const int N = 10;
804*89a1d03eSRichard int Arr[N];
805*89a1d03eSRichard 
messing_with_macros()806*89a1d03eSRichard void messing_with_macros() {
807*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
808*89a1d03eSRichard     printf("Value: %d\n", Arr[I]);
809*89a1d03eSRichard   }
810*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
811*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
812*89a1d03eSRichard   // CHECK-FIXES-NEXT:  printf("Value: %d\n", I);
813*89a1d03eSRichard 
814*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
815*89a1d03eSRichard     printf("Value: %d\n", CONT Arr[I]);
816*89a1d03eSRichard   }
817*89a1d03eSRichard 
818*89a1d03eSRichard   // Multiple macro arguments.
819*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
820*89a1d03eSRichard     TWO_PARAM(Arr[I], Arr[I]);
821*89a1d03eSRichard     THREE_PARAM(Arr[I], Arr[I], Arr[I]);
822*89a1d03eSRichard   }
823*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
824*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Arr)
825*89a1d03eSRichard   // CHECK-FIXES-NEXT: TWO_PARAM(I, I);
826*89a1d03eSRichard   // CHECK-FIXES-NEXT: THREE_PARAM(I, I, I);
827*89a1d03eSRichard }
828*89a1d03eSRichard 
829*89a1d03eSRichard } // namespace Macros
830*89a1d03eSRichard 
831*89a1d03eSRichard namespace Templates {
832*89a1d03eSRichard 
833*89a1d03eSRichard template <class Container>
set_union(Container & container)834*89a1d03eSRichard void set_union(Container &container) {
835*89a1d03eSRichard   for (typename Container::const_iterator SI = container.begin(),
836*89a1d03eSRichard        SE = container.end(); SI != SE; ++SI) {
837*89a1d03eSRichard     (void) *SI;
838*89a1d03eSRichard   }
839*89a1d03eSRichard 
840*89a1d03eSRichard   S Ss;
841*89a1d03eSRichard   for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI)
842*89a1d03eSRichard     (void) *SI;
843*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
844*89a1d03eSRichard   // CHECK-FIXES: for (auto & SI : Ss)
845*89a1d03eSRichard }
846*89a1d03eSRichard 
template_instantiation()847*89a1d03eSRichard void template_instantiation() {
848*89a1d03eSRichard   S Ss;
849*89a1d03eSRichard   set_union(Ss);
850*89a1d03eSRichard }
851*89a1d03eSRichard 
852*89a1d03eSRichard } // namespace Templates
853*89a1d03eSRichard 
854*89a1d03eSRichard namespace Lambdas {
855*89a1d03eSRichard 
capturesIndex()856*89a1d03eSRichard void capturesIndex() {
857*89a1d03eSRichard   const int N = 10;
858*89a1d03eSRichard   int Arr[N];
859*89a1d03eSRichard   // FIXME: the next four loops could be convertible, if the capture list is
860*89a1d03eSRichard   // also changed.
861*89a1d03eSRichard 
862*89a1d03eSRichard   for (int I = 0; I < N; ++I)
863*89a1d03eSRichard     auto F1 = [Arr, I]() { int R1 = Arr[I] + 1; };
864*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
865*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
866*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F1 = [Arr, &I]() { int R1 = I + 1; };
867*89a1d03eSRichard 
868*89a1d03eSRichard   for (int I = 0; I < N; ++I)
869*89a1d03eSRichard     auto F2 = [Arr, &I]() { int R2 = Arr[I] + 3; };
870*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
871*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
872*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F2 = [Arr, &I]() { int R2 = I + 3; };
873*89a1d03eSRichard 
874*89a1d03eSRichard   // FIXME: alias don't work if the index is captured.
875*89a1d03eSRichard   // Alias declared inside lambda (by value).
876*89a1d03eSRichard   for (int I = 0; I < N; ++I)
877*89a1d03eSRichard     auto F3 = [&Arr, I]() { int R3 = Arr[I]; };
878*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
879*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
880*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F3 = [&Arr, &I]() { int R3 = I; };
881*89a1d03eSRichard 
882*89a1d03eSRichard 
883*89a1d03eSRichard   for (int I = 0; I < N; ++I)
884*89a1d03eSRichard     auto F4 = [&Arr, &I]() { int R4 = Arr[I]; };
885*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
886*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
887*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F4 = [&Arr, &I]() { int R4 = I; };
888*89a1d03eSRichard 
889*89a1d03eSRichard   // Alias declared inside lambda (by reference).
890*89a1d03eSRichard   for (int I = 0; I < N; ++I)
891*89a1d03eSRichard     auto F5 = [&Arr, I]() { int &R5 = Arr[I]; };
892*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
893*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Arr)
894*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F5 = [&Arr, &I]() { int &R5 = I; };
895*89a1d03eSRichard 
896*89a1d03eSRichard 
897*89a1d03eSRichard   for (int I = 0; I < N; ++I)
898*89a1d03eSRichard     auto F6 = [&Arr, &I]() { int &R6 = Arr[I]; };
899*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
900*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Arr)
901*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F6 = [&Arr, &I]() { int &R6 = I; };
902*89a1d03eSRichard 
903*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
904*89a1d03eSRichard     auto F = [Arr, I](int k) {
905*89a1d03eSRichard       printf("%d\n", Arr[I] + k);
906*89a1d03eSRichard     };
907*89a1d03eSRichard     F(Arr[I]);
908*89a1d03eSRichard   }
909*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
910*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
911*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k)
912*89a1d03eSRichard   // CHECK-FIXES-NEXT: printf("%d\n", I + k);
913*89a1d03eSRichard   // CHECK-FIXES: F(I);
914*89a1d03eSRichard }
915*89a1d03eSRichard 
implicitCapture()916*89a1d03eSRichard void implicitCapture() {
917*89a1d03eSRichard   const int N = 10;
918*89a1d03eSRichard   int Arr[N];
919*89a1d03eSRichard   // Index is used, not convertible.
920*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
921*89a1d03eSRichard     auto G1 = [&]() {
922*89a1d03eSRichard       int R = Arr[I];
923*89a1d03eSRichard       int J = I;
924*89a1d03eSRichard     };
925*89a1d03eSRichard   }
926*89a1d03eSRichard 
927*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
928*89a1d03eSRichard     auto G2 = [=]() {
929*89a1d03eSRichard       int R = Arr[I];
930*89a1d03eSRichard       int J = I;
931*89a1d03eSRichard     };
932*89a1d03eSRichard   }
933*89a1d03eSRichard 
934*89a1d03eSRichard   // Convertible.
935*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
936*89a1d03eSRichard     auto G3 = [&]() {
937*89a1d03eSRichard       int R3 = Arr[I];
938*89a1d03eSRichard       int J3 = Arr[I] + R3;
939*89a1d03eSRichard     };
940*89a1d03eSRichard   }
941*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
942*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
943*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto G3 = [&]()
944*89a1d03eSRichard   // CHECK-FIXES-NEXT: int R3 = I;
945*89a1d03eSRichard   // CHECK-FIXES-NEXT: int J3 = I + R3;
946*89a1d03eSRichard 
947*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
948*89a1d03eSRichard     auto G4 = [=]() {
949*89a1d03eSRichard       int R4 = Arr[I] + 5;
950*89a1d03eSRichard     };
951*89a1d03eSRichard   }
952*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
953*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
954*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto G4 = [=]()
955*89a1d03eSRichard   // CHECK-FIXES-NEXT: int R4 = I + 5;
956*89a1d03eSRichard 
957*89a1d03eSRichard   // Alias by value.
958*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
959*89a1d03eSRichard     auto G5 = [&]() {
960*89a1d03eSRichard       int R5 = Arr[I];
961*89a1d03eSRichard       int J5 = 8 + R5;
962*89a1d03eSRichard     };
963*89a1d03eSRichard   }
964*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
965*89a1d03eSRichard   // CHECK-FIXES: for (int R5 : Arr)
966*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto G5 = [&]()
967*89a1d03eSRichard   // CHECK-FIXES-NEXT: int J5 = 8 + R5;
968*89a1d03eSRichard 
969*89a1d03eSRichard   // Alias by reference.
970*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
971*89a1d03eSRichard     auto G6 = [&]() {
972*89a1d03eSRichard       int &R6 = Arr[I];
973*89a1d03eSRichard       int J6 = -1 + R6;
974*89a1d03eSRichard     };
975*89a1d03eSRichard   }
976*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
977*89a1d03eSRichard   // CHECK-FIXES: for (int & R6 : Arr)
978*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto G6 = [&]()
979*89a1d03eSRichard   // CHECK-FIXES-NEXT: int J6 = -1 + R6;
980*89a1d03eSRichard }
981*89a1d03eSRichard 
iterators()982*89a1d03eSRichard void iterators() {
983*89a1d03eSRichard   dependent<int> Dep;
984*89a1d03eSRichard 
985*89a1d03eSRichard   for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
986*89a1d03eSRichard     auto H1 = [&I]() { int R = *I; };
987*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
988*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Dep)
989*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto H1 = [&I]() { int R = I; };
990*89a1d03eSRichard 
991*89a1d03eSRichard   for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
992*89a1d03eSRichard     auto H2 = [&]() { int R = *I + 2; };
993*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
994*89a1d03eSRichard   // CHECK-FIXES: for (int & I : Dep)
995*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto H2 = [&]() { int R = I + 2; };
996*89a1d03eSRichard 
997*89a1d03eSRichard   for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
998*89a1d03eSRichard        I != E; ++I)
999*89a1d03eSRichard     auto H3 = [I]() { int R = *I; };
1000*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
1001*89a1d03eSRichard   // CHECK-FIXES: for (int I : Dep)
1002*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto H3 = [&I]() { int R = I; };
1003*89a1d03eSRichard 
1004*89a1d03eSRichard   for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
1005*89a1d03eSRichard        I != E; ++I)
1006*89a1d03eSRichard     auto H4 = [&]() { int R = *I + 1; };
1007*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
1008*89a1d03eSRichard   // CHECK-FIXES: for (int I : Dep)
1009*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto H4 = [&]() { int R = I + 1; };
1010*89a1d03eSRichard 
1011*89a1d03eSRichard   for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
1012*89a1d03eSRichard        I != E; ++I)
1013*89a1d03eSRichard     auto H5 = [=]() { int R = *I; };
1014*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
1015*89a1d03eSRichard   // CHECK-FIXES: for (int R : Dep)
1016*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto H5 = [=]() { };
1017*89a1d03eSRichard }
1018*89a1d03eSRichard 
captureByValue()1019*89a1d03eSRichard void captureByValue() {
1020*89a1d03eSRichard   // When the index is captured by value, we should replace this by a capture
1021*89a1d03eSRichard   // by reference. This avoids extra copies.
1022*89a1d03eSRichard   // FIXME: this could change semantics on array or pseudoarray loops if the
1023*89a1d03eSRichard   // container is captured by copy.
1024*89a1d03eSRichard   const int N = 10;
1025*89a1d03eSRichard   int Arr[N];
1026*89a1d03eSRichard   dependent<int> Dep;
1027*89a1d03eSRichard 
1028*89a1d03eSRichard   for (int I = 0; I < N; ++I) {
1029*89a1d03eSRichard     auto C1 = [&Arr, I]() { if (Arr[I] == 1); };
1030*89a1d03eSRichard   }
1031*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
1032*89a1d03eSRichard   // CHECK-FIXES: for (int I : Arr)
1033*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto C1 = [&Arr, &I]() { if (I == 1); };
1034*89a1d03eSRichard 
1035*89a1d03eSRichard   for (unsigned I = 0; I < Dep.size(); ++I) {
1036*89a1d03eSRichard     auto C2 = [&Dep, I]() { if (Dep[I] == 2); };
1037*89a1d03eSRichard   }
1038*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
1039*89a1d03eSRichard   // CHECK-FIXES: for (int I : Dep)
1040*89a1d03eSRichard   // CHECK-FIXES-NEXT: auto C2 = [&Dep, &I]() { if (I == 2); };
1041*89a1d03eSRichard }
1042*89a1d03eSRichard 
1043*89a1d03eSRichard } // namespace Lambdas
1044*89a1d03eSRichard 
1045*89a1d03eSRichard namespace InitLists {
1046*89a1d03eSRichard 
1047*89a1d03eSRichard struct D { int Ii; };
1048*89a1d03eSRichard struct E { D Dd; };
1049*89a1d03eSRichard int g(int B);
1050*89a1d03eSRichard 
f()1051*89a1d03eSRichard void f() {
1052*89a1d03eSRichard   const unsigned N = 3;
1053*89a1d03eSRichard   int Array[N];
1054*89a1d03eSRichard 
1055*89a1d03eSRichard   // Subtrees of InitListExpr are visited twice. Test that we do not do repeated
1056*89a1d03eSRichard   // replacements.
1057*89a1d03eSRichard   for (unsigned I = 0; I < N; ++I) {
1058*89a1d03eSRichard     int A{ Array[I] };
1059*89a1d03eSRichard     int B{ g(Array[I]) };
1060*89a1d03eSRichard     int C{ g( { Array[I] } ) };
1061*89a1d03eSRichard     D Dd{ { g( { Array[I] } ) } };
1062*89a1d03eSRichard     E Ee{ { { g( { Array[I] } ) } } };
1063*89a1d03eSRichard   }
1064*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
1065*89a1d03eSRichard   // CHECK-FIXES: for (int I : Array)
1066*89a1d03eSRichard   // CHECK-FIXES-NEXT: int A{ I };
1067*89a1d03eSRichard   // CHECK-FIXES-NEXT: int B{ g(I) };
1068*89a1d03eSRichard   // CHECK-FIXES-NEXT: int C{ g( { I } ) };
1069*89a1d03eSRichard   // CHECK-FIXES-NEXT: D Dd{ { g( { I } ) } };
1070*89a1d03eSRichard   // CHECK-FIXES-NEXT: E Ee{ { { g( { I } ) } } };
1071*89a1d03eSRichard }
1072*89a1d03eSRichard 
1073*89a1d03eSRichard } // namespace InitLists
1074*89a1d03eSRichard 
bug28341()1075*89a1d03eSRichard void bug28341() {
1076*89a1d03eSRichard   char v[5];
1077*89a1d03eSRichard   for(int i = 0; i < 5; ++i) {
1078*89a1d03eSRichard       unsigned char value = v[i];
1079*89a1d03eSRichard       if (value > 127)
1080*89a1d03eSRichard         ;
1081*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
1082*89a1d03eSRichard   // CHECK-FIXES: for(unsigned char value : v)
1083*89a1d03eSRichard   // CHECK-FIXES-NEXT: if (value > 127)
1084*89a1d03eSRichard   }
1085*89a1d03eSRichard }
1086