1 // RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/modernize-loop-convert
2 
3 #include "structures.h"
4 
5 // CHECK-FIXES-NOT: for ({{.*[^:]:[^:].*}})
6 // CHECK-MESSAGES-NOT: modernize-loop-convert
7 
8 namespace Negative {
9 
10 const int N = 6;
11 int Arr[N] = {1, 2, 3, 4, 5, 6};
12 int (*pArr)[N] = &Arr;
13 int Sum = 0;
14 
15 // Checks for the Index start and end:
IndexStartAndEnd()16 void IndexStartAndEnd() {
17   for (int I = 0; I < N + 1; ++I)
18     Sum += Arr[I];
19 
20   for (int I = 0; I < N - 1; ++I)
21     Sum += Arr[I];
22 
23   for (int I = 1; I < N; ++I)
24     Sum += Arr[I];
25 
26   for (int I = 1; I < N; ++I)
27     Sum += Arr[I];
28 
29   for (int I = 0;; ++I)
30     Sum += (*pArr)[I];
31 }
32 
33 // Checks for invalid increment steps:
increment()34 void increment() {
35   for (int I = 0; I < N; --I)
36     Sum += Arr[I];
37 
38   for (int I = 0; I < N; I)
39     Sum += Arr[I];
40 
41   for (int I = 0; I < N;)
42     Sum += Arr[I];
43 
44   for (int I = 0; I < N; I += 2)
45     Sum++;
46 }
47 
48 // Checks to make sure that the Index isn't used outside of the array:
IndexUse()49 void IndexUse() {
50   for (int I = 0; I < N; ++I)
51     Arr[I] += 1 + I;
52 }
53 
54 // Check for loops that don't mention arrays
noArray()55 void noArray() {
56   for (int I = 0; I < N; ++I)
57     Sum += I;
58 
59   for (int I = 0; I < N; ++I) {
60   }
61 
62   for (int I = 0; I < N; ++I)
63     ;
64 }
65 
66 // Checks for incorrect loop variables.
mixedVariables()67 void mixedVariables() {
68   int BadIndex;
69   for (int I = 0; BadIndex < N; ++I)
70     Sum += Arr[I];
71 
72   for (int I = 0; I < N; ++BadIndex)
73     Sum += Arr[I];
74 
75   for (int I = 0; BadIndex < N; ++BadIndex)
76     Sum += Arr[I];
77 
78   for (int I = 0; BadIndex < N; ++BadIndex)
79     Sum += Arr[BadIndex];
80 }
81 
82 // Checks for multiple arrays Indexed.
multipleArrays()83 void multipleArrays() {
84   int BadArr[N];
85 
86   for (int I = 0; I < N; ++I)
87     Sum += Arr[I] + BadArr[I];
88 
89   for (int I = 0; I < N; ++I) {
90     int K = BadArr[I];
91     Sum += Arr[I] + K;
92   }
93 }
94 
95 }
96 
97 namespace NegativeIterator {
98 
99 S Ss;
100 T Tt;
101 U Tu;
102 
103 struct BadBeginEnd : T {
104   iterator notBegin();
105   iterator notEnd();
106 };
107 
notBeginOrEnd()108 void notBeginOrEnd() {
109   BadBeginEnd Bad;
110   for (T::iterator I = Bad.notBegin(), E = Bad.end();  I != E; ++I)
111     int K = *I;
112 
113   for (T::iterator I = Bad.begin(), E = Bad.notEnd();  I != E; ++I)
114     int K = *I;
115 }
116 
badLoopShapes()117 void badLoopShapes() {
118   for (T::iterator I = Tt.begin(), E = Tt.end(), F = E;  I != E; ++I)
119     int K = *I;
120 
121   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E;)
122     int K = *I;
123 
124   for (T::iterator I = Tt.begin(), E = Tt.end();; ++I)
125     int K = *I;
126 
127   T::iterator OutsideI;
128   T::iterator OutsideE;
129 
130   for (; OutsideI != OutsideE; ++OutsideI)
131     int K = *OutsideI;
132 }
133 
iteratorArrayMix()134 void iteratorArrayMix() {
135   int Lower;
136   const int N = 6;
137   for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++I)
138     int K = *I;
139 
140   for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++Lower)
141     int K = *I;
142 }
143 
144 struct ExtraConstructor : T::iterator {
145   ExtraConstructor(T::iterator, int);
146   explicit ExtraConstructor(T::iterator);
147 };
148 
badConstructor()149 void badConstructor() {
150   for (T::iterator I = ExtraConstructor(Tt.begin(), 0), E = Tt.end();
151         I != E; ++I)
152     int K = *I;
153   for (T::iterator I = ExtraConstructor(Tt.begin()), E = Tt.end();  I != E; ++I)
154     int K = *I;
155 }
156 
foo(S::iterator It)157 void foo(S::iterator It) {}
158 class Foo {public: void bar(S::iterator It); };
159 Foo Fo;
160 
iteratorUsed()161 void iteratorUsed() {
162   for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
163     foo(I);
164 
165   for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
166     Fo.bar(I);
167 
168   S::iterator Ret;
169   for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
170     Ret = I;
171 }
172 
iteratorMemberUsed()173 void iteratorMemberUsed() {
174   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
175     I.X = *I;
176 
177   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
178     int K = I.X + *I;
179 
180   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
181     int K = E.X + *I;
182 }
183 
iteratorMethodCalled()184 void iteratorMethodCalled() {
185   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
186     I.insert(3);
187 
188   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
189     if (I != I)
190       int K = 3;
191 }
192 
iteratorOperatorCalled()193 void iteratorOperatorCalled() {
194   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
195     int K = *(++I);
196 
197   for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
198     MutableVal K = *(++I);
199 }
200 
differentContainers()201 void differentContainers() {
202   T Other;
203   for (T::iterator I = Tt.begin(), E = Other.end();  I != E; ++I)
204     int K = *I;
205 
206   for (T::iterator I = Other.begin(), E = Tt.end();  I != E; ++I)
207     int K = *I;
208 
209   S OtherS;
210   for (S::iterator I = Ss.begin(), E = OtherS.end();  I != E; ++I)
211     MutableVal K = *I;
212 
213   for (S::iterator I = OtherS.begin(), E = Ss.end();  I != E; ++I)
214     MutableVal K = *I;
215 }
216 
wrongIterators()217 void wrongIterators() {
218   T::iterator Other;
219   for (T::iterator I = Tt.begin(), E = Tt.end(); I != Other; ++I)
220     int K = *I;
221 }
222 
223 struct EvilArrow : U {
224   // Please, no one ever write code like this.
225   U *operator->();
226 };
227 
differentMemberAccessTypes()228 void differentMemberAccessTypes() {
229   EvilArrow A;
230   for (EvilArrow::iterator I = A.begin(), E = A->end();  I != E; ++I)
231     Val K = *I;
232   for (EvilArrow::iterator I = A->begin(), E = A.end();  I != E; ++I)
233     Val K = *I;
234 }
235 
236 void f(const T::iterator &It, int);
237 void f(const T &It, int);
238 void g(T &It, int);
239 
iteratorPassedToFunction()240 void iteratorPassedToFunction() {
241   for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
242     f(I, *I);
243 }
244 
245 // FIXME: These tests can be removed if this tool ever does enough analysis to
246 // decide that this is a safe transformation. Until then, we don't want it
247 // applied.
iteratorDefinedOutside()248 void iteratorDefinedOutside() {
249   T::iterator TheEnd = Tt.end();
250   for (T::iterator I = Tt.begin(); I != TheEnd; ++I)
251     int K = *I;
252 
253   T::iterator TheBegin = Tt.begin();
254   for (T::iterator E = Tt.end(); TheBegin != E; ++TheBegin)
255     int K = *TheBegin;
256 }
257 
258 } // namespace NegativeIterator
259 
260 namespace NegativePseudoArray {
261 
262 const int N = 6;
263 dependent<int> V;
264 dependent<int> *Pv;
265 
266 int Sum = 0;
267 
268 // Checks for the Index start and end:
IndexStartAndEnd()269 void IndexStartAndEnd() {
270   for (int I = 0; I < V.size() + 1; ++I)
271     Sum += V[I];
272 
273   for (int I = 0; I < V.size() - 1; ++I)
274     Sum += V[I];
275 
276   for (int I = 1; I < V.size(); ++I)
277     Sum += V[I];
278 
279   for (int I = 1; I < V.size(); ++I)
280     Sum += V[I];
281 
282   for (int I = 0;; ++I)
283     Sum += (*Pv)[I];
284 }
285 
286 // Checks for invalid increment steps:
increment()287 void increment() {
288   for (int I = 0; I < V.size(); --I)
289     Sum += V[I];
290 
291   for (int I = 0; I < V.size(); I)
292     Sum += V[I];
293 
294   for (int I = 0; I < V.size();)
295     Sum += V[I];
296 
297   for (int I = 0; I < V.size(); I += 2)
298     Sum++;
299 }
300 
301 // Checks to make sure that the Index isn't used outside of the container:
IndexUse()302 void IndexUse() {
303   for (int I = 0; I < V.size(); ++I)
304     V[I] += 1 + I;
305 }
306 
307 // Checks for incorrect loop variables.
mixedVariables()308 void mixedVariables() {
309   int BadIndex;
310   for (int I = 0; BadIndex < V.size(); ++I)
311     Sum += V[I];
312 
313   for (int I = 0; I < V.size(); ++BadIndex)
314     Sum += V[I];
315 
316   for (int I = 0; BadIndex < V.size(); ++BadIndex)
317     Sum += V[I];
318 
319   for (int I = 0; BadIndex < V.size(); ++BadIndex)
320     Sum += V[BadIndex];
321 }
322 
323 // Checks for an array Indexed in addition to the container.
multipleArrays()324 void multipleArrays() {
325   int BadArr[N];
326 
327   for (int I = 0; I < V.size(); ++I)
328     Sum += V[I] + BadArr[I];
329 
330   for (int I = 0; I < V.size(); ++I)
331     Sum += BadArr[I];
332 
333   for (int I = 0; I < V.size(); ++I) {
334     int K = BadArr[I];
335     Sum += K + 2;
336   }
337 
338   for (int I = 0; I < V.size(); ++I) {
339     int K = BadArr[I];
340     Sum += V[I] + K;
341   }
342 }
343 
344 // Checks for multiple containers being Indexed container.
multipleContainers()345 void multipleContainers() {
346   dependent<int> BadArr;
347 
348   for (int I = 0; I < V.size(); ++I)
349     Sum += V[I] + BadArr[I];
350 
351   for (int I = 0; I < V.size(); ++I)
352     Sum += BadArr[I];
353 
354   for (int I = 0; I < V.size(); ++I) {
355     int K = BadArr[I];
356     Sum += K + 2;
357   }
358 
359   for (int I = 0; I < V.size(); ++I) {
360     int K = BadArr[I];
361     Sum += V[I] + K;
362   }
363 }
364 
365 // Check to make sure that dereferenced pointers-to-containers behave nicely.
derefContainer()366 void derefContainer() {
367   // Note the dependent<T>::operator*() returns another dependent<T>.
368   // This test makes sure that we don't allow an arbitrary number of *'s.
369   for (int I = 0; I < Pv->size(); ++I)
370     Sum += (**Pv).at(I);
371 
372   for (int I = 0; I < Pv->size(); ++I)
373     Sum += (**Pv)[I];
374 }
375 
wrongEnd()376 void wrongEnd() {
377   int Bad;
378   for (int I = 0, E = V.size(); I < Bad; ++I)
379     Sum += V[I];
380 }
381 
382 // Checks to see that non-const member functions are not called on the container
383 // object.
384 // These could be conceivably allowed with a lower required confidence level.
memberFunctionCalled()385 void memberFunctionCalled() {
386   for (int I = 0; I < V.size(); ++I) {
387     Sum += V[I];
388     V.foo();
389   }
390 
391   for (int I = 0; I < V.size(); ++I) {
392     Sum += V[I];
393     dependent<int>::iterator It = V.begin();
394   }
395 }
396 
397 } // namespace NegativePseudoArray
398 
399 namespace NegativeMultiEndCall {
400 
401 S Ss;
402 T Tt;
403 U Uu;
404 
405 void f(X);
406 void f(S);
407 void f(T);
408 
complexContainer()409 void complexContainer() {
410   X Xx;
411   for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end();  I != E; ++I) {
412     f(Xx);
413     MutableVal K = *I;
414   }
415 
416   for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end();  I != E; ++I) {
417     f(Xx);
418     int K = *I;
419   }
420 
421   for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end();  I != E; ++I) {
422     f(Xx.Ss);
423     MutableVal K = *I;
424   }
425 
426   for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end();  I != E; ++I) {
427     f(Xx.Tt);
428     int K = *I;
429   }
430 
431   for (S::iterator I = Xx.getS().begin(), E = Xx.getS().end();  I != E; ++I) {
432     f(Xx.getS());
433     MutableVal K = *I;
434   }
435 
436   X Exes[5];
437   int Index = 0;
438 
439   for (S::iterator I = Exes[Index].getS().begin(),
440                    E = Exes[Index].getS().end();
441         I != E; ++I) {
442     Index++;
443     MutableVal K = *I;
444   }
445 }
446 
447 } // namespace NegativeMultiEndCall
448 
449 namespace NoUsages {
450 
451 const int N = 6;
452 int Arr[N] = {1, 2, 3, 4, 5, 6};
453 S Ss;
454 dependent<int> V;
455 int Count = 0;
456 
457 void foo();
458 
f()459 void f() {
460   for (int I = 0; I < N; ++I) {}
461   for (int I = 0; I < N; ++I)
462     printf("Hello world\n");
463   for (int I = 0; I < N; ++I)
464     ++Count;
465   for (int I = 0; I < N; ++I)
466     foo();
467 
468   for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I) {}
469   for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
470     printf("Hello world\n");
471   for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
472     ++Count;
473   for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
474     foo();
475 
476   for (int I = 0; I < V.size(); ++I) {}
477   for (int I = 0; I < V.size(); ++I)
478     printf("Hello world\n");
479   for (int I = 0; I < V.size(); ++I)
480     ++Count;
481   for (int I = 0; I < V.size(); ++I)
482     foo();
483 }
484 
485 } // namespace NoUsages
486