189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert 289a1d03eSRichard 389a1d03eSRichard #include "structures.h" 489a1d03eSRichard 589a1d03eSRichard namespace Array { 689a1d03eSRichard 789a1d03eSRichard const int N = 6; 889a1d03eSRichard const int NMinusOne = N - 1; 989a1d03eSRichard int Arr[N] = {1, 2, 3, 4, 5, 6}; 1089a1d03eSRichard const int ConstArr[N] = {1, 2, 3, 4, 5, 6}; 1189a1d03eSRichard int (*PArr)[N] = &Arr; 1289a1d03eSRichard 1389a1d03eSRichard void f() { 1489a1d03eSRichard int Sum = 0; 1589a1d03eSRichard 1689a1d03eSRichard for (int I = 0; I < N; ++I) { 1789a1d03eSRichard Sum += Arr[I]; 1889a1d03eSRichard int K; 1989a1d03eSRichard } 2089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert] 2189a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 2289a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I; 2389a1d03eSRichard // CHECK-FIXES-NEXT: int K; 2489a1d03eSRichard 2589a1d03eSRichard for (int I = 0; I < N; ++I) { 2689a1d03eSRichard printf("Fibonacci number is %d\n", Arr[I]); 2789a1d03eSRichard Sum += Arr[I] + 2; 2889a1d03eSRichard } 2989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 3089a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 3189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 3289a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 3389a1d03eSRichard 3489a1d03eSRichard for (int I = 0; I < N; ++I) { 3589a1d03eSRichard int X = Arr[I]; 3689a1d03eSRichard int Y = Arr[I] + 2; 3789a1d03eSRichard } 3889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 3989a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 4089a1d03eSRichard // CHECK-FIXES-NEXT: int X = I; 4189a1d03eSRichard // CHECK-FIXES-NEXT: int Y = I + 2; 4289a1d03eSRichard 4389a1d03eSRichard for (int I = 0; I < N; ++I) { 4489a1d03eSRichard int X = N; 4589a1d03eSRichard X = Arr[I]; 4689a1d03eSRichard } 4789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 4889a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 4989a1d03eSRichard // CHECK-FIXES-NEXT: int X = N; 5089a1d03eSRichard // CHECK-FIXES-NEXT: X = I; 5189a1d03eSRichard 5289a1d03eSRichard for (int I = 0; I < N; ++I) { 5389a1d03eSRichard Arr[I] += 1; 5489a1d03eSRichard } 5589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 5689a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 5789a1d03eSRichard // CHECK-FIXES-NEXT: I += 1; 5889a1d03eSRichard 5989a1d03eSRichard for (int I = 0; I < N; ++I) { 6089a1d03eSRichard int X = Arr[I] + 2; 6189a1d03eSRichard Arr[I]++; 6289a1d03eSRichard } 6389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 6489a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 6589a1d03eSRichard // CHECK-FIXES-NEXT: int X = I + 2; 6689a1d03eSRichard // CHECK-FIXES-NEXT: I++; 6789a1d03eSRichard 6889a1d03eSRichard for (int I = 0; I < N; ++I) { 6989a1d03eSRichard Arr[I] = 4 + Arr[I]; 7089a1d03eSRichard } 7189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 7289a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 7389a1d03eSRichard // CHECK-FIXES-NEXT: I = 4 + I; 7489a1d03eSRichard 7589a1d03eSRichard for (int I = 0; I < NMinusOne + 1; ++I) { 7689a1d03eSRichard Sum += Arr[I]; 7789a1d03eSRichard } 7889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 7989a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 8089a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I; 8189a1d03eSRichard 8289a1d03eSRichard for (int I = 0; I < N; ++I) { 8389a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 8489a1d03eSRichard Sum += Arr[I] + 2; 8589a1d03eSRichard } 8689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 8789a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 8889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 8989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 9089a1d03eSRichard 915e83b265SDanny Mösch int Matrix[N][12]; 925e83b265SDanny Mösch unsigned size = 0; 935e83b265SDanny Mösch for (int I = 0; I < N; ++I) { 945e83b265SDanny Mösch size += sizeof(Matrix[I]); 955e83b265SDanny Mösch size += sizeof Matrix[I]; 965e83b265SDanny Mösch size += sizeof((Matrix[I])); 975e83b265SDanny Mösch } 985e83b265SDanny Mösch // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead 995e83b265SDanny Mösch // CHECK-FIXES: for (auto & I : Matrix) 1005e83b265SDanny Mösch // CHECK-FIXES-NEXT: size += sizeof(I); 1015e83b265SDanny Mösch // CHECK-FIXES-NEXT: size += sizeof I; 1025e83b265SDanny Mösch // CHECK-FIXES-NEXT: size += sizeof(I); 1035e83b265SDanny Mösch 10489a1d03eSRichard Val Teas[N]; 10589a1d03eSRichard for (int I = 0; I < N; ++I) { 10689a1d03eSRichard Teas[I].g(); 10789a1d03eSRichard } 10889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 10989a1d03eSRichard // CHECK-FIXES: for (auto & Tea : Teas) 11089a1d03eSRichard // CHECK-FIXES-NEXT: Tea.g(); 11189a1d03eSRichard 11289a1d03eSRichard for (int I = 0; N > I; ++I) { 11389a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 11489a1d03eSRichard Sum += Arr[I] + 2; 11589a1d03eSRichard } 11689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 11789a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 11889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 11989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 12089a1d03eSRichard 12189a1d03eSRichard for (int I = 0; N != I; ++I) { 12289a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 12389a1d03eSRichard Sum += Arr[I] + 2; 12489a1d03eSRichard } 12589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 12689a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 12789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 12889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 12989a1d03eSRichard 13089a1d03eSRichard for (int I = 0; I != N; ++I) { 13189a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 13289a1d03eSRichard Sum += Arr[I] + 2; 13389a1d03eSRichard } 13489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 13589a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 13689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 13789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 13889a1d03eSRichard } 13989a1d03eSRichard 14089a1d03eSRichard const int *constArray() { 14189a1d03eSRichard for (int I = 0; I < N; ++I) { 14289a1d03eSRichard printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]); 14389a1d03eSRichard } 14489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 14589a1d03eSRichard // CHECK-FIXES: for (int I : ConstArr) 14689a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I); 14789a1d03eSRichard 14889a1d03eSRichard const NonTriviallyCopyable NonCopy[N]{}; 14989a1d03eSRichard for (int I = 0; I < N; ++I) { 15089a1d03eSRichard printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X); 15189a1d03eSRichard } 15289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 15389a1d03eSRichard // CHECK-FIXES: for (const auto & I : NonCopy) 15489a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 15589a1d03eSRichard 15689a1d03eSRichard const TriviallyCopyableButBig Big[N]{}; 15789a1d03eSRichard for (int I = 0; I < N; ++I) { 15889a1d03eSRichard printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X); 15989a1d03eSRichard } 16089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 16189a1d03eSRichard // CHECK-FIXES: for (const auto & I : Big) 16289a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 16389a1d03eSRichard 16489a1d03eSRichard bool Something = false; 16589a1d03eSRichard for (int I = 0; I < N; ++I) { 16689a1d03eSRichard if (Something) 16789a1d03eSRichard return &ConstArr[I]; 16889a1d03eSRichard } 16989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 17089a1d03eSRichard // CHECK-FIXES: for (const int & I : ConstArr) 17189a1d03eSRichard // CHECK-FIXES-NEXT: if (Something) 17289a1d03eSRichard // CHECK-FIXES-NEXT: return &I; 17389a1d03eSRichard } 17489a1d03eSRichard 17589a1d03eSRichard struct HasArr { 17689a1d03eSRichard int Arr[N]; 17789a1d03eSRichard Val ValArr[N]; 17889a1d03eSRichard void implicitThis() { 17989a1d03eSRichard for (int I = 0; I < N; ++I) { 18089a1d03eSRichard printf("%d", Arr[I]); 18189a1d03eSRichard } 18289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 18389a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 18489a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 18589a1d03eSRichard 18689a1d03eSRichard for (int I = 0; I < N; ++I) { 18789a1d03eSRichard printf("%d", ValArr[I].X); 18889a1d03eSRichard } 18989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 19089a1d03eSRichard // CHECK-FIXES: for (auto & I : ValArr) 19189a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 19289a1d03eSRichard } 19389a1d03eSRichard 19489a1d03eSRichard void explicitThis() { 19589a1d03eSRichard for (int I = 0; I < N; ++I) { 19689a1d03eSRichard printf("%d", this->Arr[I]); 19789a1d03eSRichard } 19889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 19989a1d03eSRichard // CHECK-FIXES: for (int I : this->Arr) 20089a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 20189a1d03eSRichard 20289a1d03eSRichard for (int I = 0; I < N; ++I) { 20389a1d03eSRichard printf("%d", this->ValArr[I].X); 20489a1d03eSRichard } 20589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 20689a1d03eSRichard // CHECK-FIXES: for (auto & I : this->ValArr) 20789a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 20889a1d03eSRichard } 20989a1d03eSRichard }; 21089a1d03eSRichard 21189a1d03eSRichard struct HasIndirectArr { 21289a1d03eSRichard HasArr HA; 21389a1d03eSRichard void implicitThis() { 21489a1d03eSRichard for (int I = 0; I < N; ++I) { 21589a1d03eSRichard printf("%d", HA.Arr[I]); 21689a1d03eSRichard } 21789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 21889a1d03eSRichard // CHECK-FIXES: for (int I : HA.Arr) 21989a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 22089a1d03eSRichard 22189a1d03eSRichard for (int I = 0; I < N; ++I) { 22289a1d03eSRichard printf("%d", HA.ValArr[I].X); 22389a1d03eSRichard } 22489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 22589a1d03eSRichard // CHECK-FIXES: for (auto & I : HA.ValArr) 22689a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 22789a1d03eSRichard } 22889a1d03eSRichard 22989a1d03eSRichard void explicitThis() { 23089a1d03eSRichard for (int I = 0; I < N; ++I) { 23189a1d03eSRichard printf("%d", this->HA.Arr[I]); 23289a1d03eSRichard } 23389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 23489a1d03eSRichard // CHECK-FIXES: for (int I : this->HA.Arr) 23589a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 23689a1d03eSRichard 23789a1d03eSRichard for (int I = 0; I < N; ++I) { 23889a1d03eSRichard printf("%d", this->HA.ValArr[I].X); 23989a1d03eSRichard } 24089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 24189a1d03eSRichard // CHECK-FIXES: for (auto & I : this->HA.ValArr) 24289a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 24389a1d03eSRichard } 24489a1d03eSRichard }; 24589a1d03eSRichard 24689a1d03eSRichard // Loops whose bounds are value-dependent should not be converted. 24789a1d03eSRichard template <int N> 24889a1d03eSRichard void dependentExprBound() { 24989a1d03eSRichard for (int I = 0; I < N; ++I) 25089a1d03eSRichard Arr[I] = 0; 25189a1d03eSRichard } 25289a1d03eSRichard template void dependentExprBound<20>(); 25389a1d03eSRichard 25489a1d03eSRichard void memberFunctionPointer() { 25589a1d03eSRichard Val V; 25689a1d03eSRichard void (Val::*mfpArr[N])(void) = {&Val::g}; 25789a1d03eSRichard for (int I = 0; I < N; ++I) 25889a1d03eSRichard (V.*mfpArr[I])(); 25989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 26089a1d03eSRichard // CHECK-FIXES: for (auto & I : mfpArr) 26189a1d03eSRichard // CHECK-FIXES-NEXT: (V.*I)(); 26289a1d03eSRichard 26389a1d03eSRichard struct Foo { 26489a1d03eSRichard int (Val::*f)(); 26589a1d03eSRichard } Foo[N]; 26689a1d03eSRichard 26789a1d03eSRichard for (int I = 0; I < N; ++I) 26889a1d03eSRichard int R = (V.*(Foo[I].f))(); 26989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 27089a1d03eSRichard // CHECK-FIXES: for (auto & I : Foo) 27189a1d03eSRichard // CHECK-FIXES-NEXT: int R = (V.*(I.f))(); 27289a1d03eSRichard 27389a1d03eSRichard } 27489a1d03eSRichard 27589a1d03eSRichard } // namespace Array 27689a1d03eSRichard 27789a1d03eSRichard namespace Iterator { 27889a1d03eSRichard 27989a1d03eSRichard void f() { 28089a1d03eSRichard /// begin()/end() - based for loops here: 28189a1d03eSRichard T Tt; 28289a1d03eSRichard for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) { 28389a1d03eSRichard printf("I found %d\n", *It); 28489a1d03eSRichard } 28589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 28689a1d03eSRichard // CHECK-FIXES: for (int & It : Tt) 28789a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 28889a1d03eSRichard 28989a1d03eSRichard // Do not crash because of Qq.begin() converting. Q::iterator converts with a 29089a1d03eSRichard // conversion operator, which has no name, to Q::const_iterator. 29189a1d03eSRichard Q Qq; 29289a1d03eSRichard for (Q::const_iterator It = Qq.begin(), E = Qq.end(); It != E; ++It) { 29389a1d03eSRichard printf("I found %d\n", *It); 29489a1d03eSRichard } 29589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 29689a1d03eSRichard // CHECK-FIXES: for (int & It : Qq) 29789a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 29889a1d03eSRichard 29989a1d03eSRichard T *Pt; 30089a1d03eSRichard for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) { 30189a1d03eSRichard printf("I found %d\n", *It); 30289a1d03eSRichard } 30389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 30489a1d03eSRichard // CHECK-FIXES: for (int & It : *Pt) 30589a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 30689a1d03eSRichard 30789a1d03eSRichard S Ss; 30889a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 30989a1d03eSRichard printf("s has value %d\n", (*It).X); 31089a1d03eSRichard } 31189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 31289a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 31389a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 31489a1d03eSRichard 31589a1d03eSRichard S *Ps; 31689a1d03eSRichard for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 31789a1d03eSRichard printf("s has value %d\n", (*It).X); 31889a1d03eSRichard } 31989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 32089a1d03eSRichard // CHECK-FIXES: for (auto & P : *Ps) 32189a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 32289a1d03eSRichard 32389a1d03eSRichard for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) { 32489a1d03eSRichard printf("s has value %d\n", (*It).X); 32589a1d03eSRichard } 32689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 32789a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 32889a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 32989a1d03eSRichard 33089a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 33189a1d03eSRichard printf("s has value %d\n", It->X); 33289a1d03eSRichard } 33389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 33489a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 33589a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 33689a1d03eSRichard 33789a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 33889a1d03eSRichard It->X = 3; 33989a1d03eSRichard } 34089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 34189a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 34289a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 34389a1d03eSRichard 34489a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 34589a1d03eSRichard (*It).X = 3; 34689a1d03eSRichard } 34789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 34889a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 34989a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 35089a1d03eSRichard 35189a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 35289a1d03eSRichard It->nonConstFun(4, 5); 35389a1d03eSRichard } 35489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 35589a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 35689a1d03eSRichard // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); 35789a1d03eSRichard 35889a1d03eSRichard U Uu; 35989a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 36089a1d03eSRichard printf("s has value %d\n", It->X); 36189a1d03eSRichard } 36289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 36389a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 36489a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 36589a1d03eSRichard 36689a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 36789a1d03eSRichard printf("s has value %d\n", (*It).X); 36889a1d03eSRichard } 36989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 37089a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 37189a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 37289a1d03eSRichard 37389a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 37489a1d03eSRichard Val* a = It.operator->(); 37589a1d03eSRichard } 37689a1d03eSRichard 37789a1d03eSRichard U::iterator A; 37889a1d03eSRichard for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I) 37989a1d03eSRichard int K = A->X + I->X; 38089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 38189a1d03eSRichard // CHECK-FIXES: for (auto & I : Uu) 38289a1d03eSRichard // CHECK-FIXES-NEXT: int K = A->X + I.X; 38389a1d03eSRichard 38489a1d03eSRichard dependent<int> V; 38589a1d03eSRichard for (dependent<int>::iterator It = V.begin(), E = V.end(); 38689a1d03eSRichard It != E; ++It) { 38789a1d03eSRichard printf("Fibonacci number is %d\n", *It); 38889a1d03eSRichard } 38989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 39089a1d03eSRichard // CHECK-FIXES: for (int & It : V) 39189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 39289a1d03eSRichard 39389a1d03eSRichard for (dependent<int>::iterator It(V.begin()), E = V.end(); 39489a1d03eSRichard It != E; ++It) { 39589a1d03eSRichard printf("Fibonacci number is %d\n", *It); 39689a1d03eSRichard } 39789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 39889a1d03eSRichard // CHECK-FIXES: for (int & It : V) 39989a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 40089a1d03eSRichard 40189a1d03eSRichard doublyDependent<int, int> Intmap; 40289a1d03eSRichard for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end(); 40389a1d03eSRichard It != E; ++It) { 40489a1d03eSRichard printf("Intmap[%d] = %d", It->first, It->second); 40589a1d03eSRichard } 40689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 40789a1d03eSRichard // CHECK-FIXES: for (auto & It : Intmap) 40889a1d03eSRichard // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second); 40989a1d03eSRichard 41089a1d03eSRichard // PtrSet's iterator dereferences by value so auto & can't be used. 41189a1d03eSRichard { 41289a1d03eSRichard PtrSet<int *> Val_int_ptrs; 41389a1d03eSRichard for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(), 41489a1d03eSRichard E = Val_int_ptrs.end(); 41589a1d03eSRichard I != E; ++I) { 41689a1d03eSRichard (void) *I; 41789a1d03eSRichard } 41889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 41989a1d03eSRichard // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) 42089a1d03eSRichard } 42189a1d03eSRichard 42289a1d03eSRichard // This container uses an iterator where the dereference type is a typedef of 42389a1d03eSRichard // a reference type. Make sure non-const auto & is still used. A failure here 42489a1d03eSRichard // means canonical types aren't being tested. 42589a1d03eSRichard { 42689a1d03eSRichard TypedefDerefContainer<int> Int_ptrs; 42789a1d03eSRichard for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(), 42889a1d03eSRichard E = Int_ptrs.end(); 42989a1d03eSRichard I != E; ++I) { 43089a1d03eSRichard (void) *I; 43189a1d03eSRichard } 43289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 43389a1d03eSRichard // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) 43489a1d03eSRichard } 43589a1d03eSRichard 43689a1d03eSRichard { 43789a1d03eSRichard // Iterators returning an rvalue reference should disqualify the loop from 43889a1d03eSRichard // transformation. 43989a1d03eSRichard RValueDerefContainer<int> Container; 44089a1d03eSRichard for (RValueDerefContainer<int>::iterator I = Container.begin(), 44189a1d03eSRichard E = Container.end(); 44289a1d03eSRichard I != E; ++I) { 44389a1d03eSRichard (void) *I; 44489a1d03eSRichard } 44589a1d03eSRichard } 44689a1d03eSRichard 44789a1d03eSRichard dependent<Val *> Dpp; 44889a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 44989a1d03eSRichard printf("%d\n", (**I).X); 45089a1d03eSRichard } 45189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 45289a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 45389a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", (*I).X); 45489a1d03eSRichard 45589a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 45689a1d03eSRichard printf("%d\n", (*I)->X); 45789a1d03eSRichard } 45889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 45989a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 46089a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I->X); 4616a1f8ef8SChris Cotter 4626a1f8ef8SChris Cotter for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) { 4636a1f8ef8SChris Cotter printf("s0 has value %d\n", (*It).X); 4646a1f8ef8SChris Cotter } 4656a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 4666a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : Ss) 4676a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X); 4686a1f8ef8SChris Cotter 4696a1f8ef8SChris Cotter for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) { 4706a1f8ef8SChris Cotter printf("s1 has value %d\n", (*It).X); 4716a1f8ef8SChris Cotter } 4726a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 4736a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : Ss) 4746a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X); 4756a1f8ef8SChris Cotter 4766a1f8ef8SChris Cotter for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) { 4776a1f8ef8SChris Cotter printf("s2 has value %d\n", (*It).X); 4786a1f8ef8SChris Cotter } 4796a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 4806a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : *Ps) 4816a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X); 4826a1f8ef8SChris Cotter 4836a1f8ef8SChris Cotter for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) { 4846a1f8ef8SChris Cotter printf("s3 has value %d\n", (*It).X); 4856a1f8ef8SChris Cotter } 4866a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 4876a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : *Ps) 4886a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X); 4896a1f8ef8SChris Cotter 4906a1f8ef8SChris Cotter for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) { 4916a1f8ef8SChris Cotter printf("s4 has value %d\n", (*It).X); 4926a1f8ef8SChris Cotter } 4936a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 4946a1f8ef8SChris Cotter // CHECK-FIXES: for (auto It : Ss) 4956a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X); 49689a1d03eSRichard } 49789a1d03eSRichard 49889a1d03eSRichard // Tests to verify the proper use of auto where the init variable type and the 49989a1d03eSRichard // initializer type differ or are mostly the same except for const qualifiers. 50089a1d03eSRichard void different_type() { 50189a1d03eSRichard // Ss.begin() returns a type 'iterator' which is just a non-const pointer and 50289a1d03eSRichard // differs from const_iterator only on the const qualification. 50389a1d03eSRichard S Ss; 50489a1d03eSRichard for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 50589a1d03eSRichard printf("s has value %d\n", (*It).X); 50689a1d03eSRichard } 50789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 50889a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 50989a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 51089a1d03eSRichard 51189a1d03eSRichard S *Ps; 51289a1d03eSRichard for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 51389a1d03eSRichard printf("s has value %d\n", (*It).X); 51489a1d03eSRichard } 51589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 51689a1d03eSRichard // CHECK-FIXES: for (auto P : *Ps) 51789a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 51889a1d03eSRichard 51989a1d03eSRichard dependent<int> V; 52089a1d03eSRichard for (dependent<int>::const_iterator It = V.begin(), E = V.end(); 52189a1d03eSRichard It != E; ++It) { 52289a1d03eSRichard printf("Fibonacci number is %d\n", *It); 52389a1d03eSRichard } 52489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 52589a1d03eSRichard // CHECK-FIXES: for (int It : V) 52689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 52789a1d03eSRichard 52889a1d03eSRichard for (dependent<int>::const_iterator It(V.begin()), E = V.end(); 52989a1d03eSRichard It != E; ++It) { 53089a1d03eSRichard printf("Fibonacci number is %d\n", *It); 53189a1d03eSRichard } 53289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 53389a1d03eSRichard // CHECK-FIXES: for (int It : V) 53489a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 53589a1d03eSRichard } 53689a1d03eSRichard 53789a1d03eSRichard // Tests to ensure that an implicit 'this' is picked up as the container. 53889a1d03eSRichard // If member calls are made to 'this' within the loop, the transform becomes 53989a1d03eSRichard // risky as these calls may affect state that affects the loop. 54089a1d03eSRichard class C { 54189a1d03eSRichard public: 54289a1d03eSRichard typedef MutableVal *iterator; 54389a1d03eSRichard typedef const MutableVal *const_iterator; 54489a1d03eSRichard 54589a1d03eSRichard iterator begin(); 54689a1d03eSRichard iterator end(); 54789a1d03eSRichard const_iterator begin() const; 54889a1d03eSRichard const_iterator end() const; 54989a1d03eSRichard 55089a1d03eSRichard void doSomething(); 55189a1d03eSRichard void doSomething() const; 55289a1d03eSRichard 55389a1d03eSRichard void doLoop() { 55489a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 55589a1d03eSRichard (void) *I; 55689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 55789a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 55889a1d03eSRichard 55989a1d03eSRichard for (iterator I = C::begin(), E = C::end(); I != E; ++I) 56089a1d03eSRichard (void) *I; 56189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 56289a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 56389a1d03eSRichard 56489a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) { 56589a1d03eSRichard (void) *I; 56689a1d03eSRichard doSomething(); 56789a1d03eSRichard } 56889a1d03eSRichard 56989a1d03eSRichard for (iterator I = begin(); I != end(); ++I) 57089a1d03eSRichard (void) *I; 57189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 57289a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 57389a1d03eSRichard 57489a1d03eSRichard for (iterator I = begin(); I != end(); ++I) { 57589a1d03eSRichard (void) *I; 57689a1d03eSRichard doSomething(); 57789a1d03eSRichard } 57889a1d03eSRichard } 57989a1d03eSRichard 58089a1d03eSRichard void doLoop() const { 58189a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) 58289a1d03eSRichard (void) *I; 58389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 58489a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 58589a1d03eSRichard 58689a1d03eSRichard for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) 58789a1d03eSRichard (void) *I; 58889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 58989a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 59089a1d03eSRichard 59189a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) { 59289a1d03eSRichard (void) *I; 59389a1d03eSRichard doSomething(); 59489a1d03eSRichard } 59589a1d03eSRichard } 59689a1d03eSRichard }; 59789a1d03eSRichard 59889a1d03eSRichard class C2 { 59989a1d03eSRichard public: 60089a1d03eSRichard typedef MutableVal *iterator; 60189a1d03eSRichard 60289a1d03eSRichard iterator begin() const; 60389a1d03eSRichard iterator end() const; 60489a1d03eSRichard 60589a1d03eSRichard void doLoop() { 60689a1d03eSRichard // The implicit 'this' will have an Implicit cast to const C2* wrapped 60789a1d03eSRichard // around it. Make sure the replacement still happens. 60889a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 60989a1d03eSRichard (void) *I; 61089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 61189a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 61289a1d03eSRichard } 61389a1d03eSRichard }; 61489a1d03eSRichard 61589a1d03eSRichard } // namespace Iterator 61689a1d03eSRichard 61789a1d03eSRichard namespace PseudoArray { 61889a1d03eSRichard 61989a1d03eSRichard const int N = 6; 62089a1d03eSRichard dependent<int> V; 62189a1d03eSRichard dependent<int> *Pv; 62289a1d03eSRichard const dependent<NonTriviallyCopyable> Constv; 62389a1d03eSRichard const dependent<NonTriviallyCopyable> *Pconstv; 62489a1d03eSRichard 62589a1d03eSRichard transparent<dependent<int>> Cv; 626e4329520SChris Cotter dependent_derived<int> VD; 62789a1d03eSRichard 62889a1d03eSRichard void f() { 62989a1d03eSRichard int Sum = 0; 63089a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 63189a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 63289a1d03eSRichard Sum += V[I] + 2; 63389a1d03eSRichard } 63489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 63589a1d03eSRichard // CHECK-FIXES: for (int I : V) 63689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 63789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 63889a1d03eSRichard 63989a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 64089a1d03eSRichard printf("Fibonacci number is %d\n", V.at(I)); 64189a1d03eSRichard Sum += V.at(I) + 2; 64289a1d03eSRichard } 64389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 64489a1d03eSRichard // CHECK-FIXES: for (int I : V) 64589a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 64689a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 64789a1d03eSRichard 64889a1d03eSRichard for (int I = 0, E = Pv->size(); I < E; ++I) { 64989a1d03eSRichard printf("Fibonacci number is %d\n", Pv->at(I)); 65089a1d03eSRichard Sum += Pv->at(I) + 2; 65189a1d03eSRichard } 65289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 65389a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 65489a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 65589a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 65689a1d03eSRichard 65789a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 65889a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 65989a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 66089a1d03eSRichard // explicitly. 66189a1d03eSRichard for (int I = 0; I < Pv->size(); ++I) { 66289a1d03eSRichard printf("Fibonacci number is %d\n", (*Pv).at(I)); 66389a1d03eSRichard Sum += (*Pv)[I] + 2; 66489a1d03eSRichard } 66589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 66689a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 66789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 66889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 66989a1d03eSRichard 67089a1d03eSRichard for (int I = 0; I < Cv->size(); ++I) { 67189a1d03eSRichard printf("Fibonacci number is %d\n", Cv->at(I)); 67289a1d03eSRichard Sum += Cv->at(I) + 2; 67389a1d03eSRichard } 67489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 67589a1d03eSRichard // CHECK-FIXES: for (int I : *Cv) 67689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 67789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 67889a1d03eSRichard 67989a1d03eSRichard for (int I = 0, E = V.size(); E > I; ++I) { 68089a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 68189a1d03eSRichard Sum += V[I] + 2; 68289a1d03eSRichard } 68389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 68489a1d03eSRichard // CHECK-FIXES: for (int I : V) 68589a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 68689a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 68789a1d03eSRichard 68889a1d03eSRichard for (int I = 0, E = V.size(); I != E; ++I) { 68989a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 69089a1d03eSRichard Sum += V[I] + 2; 69189a1d03eSRichard } 69289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 69389a1d03eSRichard // CHECK-FIXES: for (int I : V) 69489a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 69589a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 69689a1d03eSRichard 69789a1d03eSRichard for (int I = 0, E = V.size(); E != I; ++I) { 69889a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 69989a1d03eSRichard Sum += V[I] + 2; 70089a1d03eSRichard } 70189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 70289a1d03eSRichard // CHECK-FIXES: for (int I : V) 70389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 70489a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 705e4329520SChris Cotter 706e4329520SChris Cotter for (int I = 0, E = VD.size(); E != I; ++I) { 707e4329520SChris Cotter printf("Fibonacci number is %d\n", VD[I]); 708e4329520SChris Cotter Sum += VD[I] + 2; 709e4329520SChris Cotter } 710e4329520SChris Cotter // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 711e4329520SChris Cotter // CHECK-FIXES: for (int I : VD) 712e4329520SChris Cotter // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 713e4329520SChris Cotter // CHECK-FIXES-NEXT: Sum += I + 2; 7146a1f8ef8SChris Cotter 7156a1f8ef8SChris Cotter for (int I = 0, E = size(V); E != I; ++I) { 7166a1f8ef8SChris Cotter printf("Fibonacci number is %d\n", V[I]); 7176a1f8ef8SChris Cotter Sum += V[I] + 2; 7186a1f8ef8SChris Cotter } 7196a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 7206a1f8ef8SChris Cotter // CHECK-FIXES: for (int I : V) 7216a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 7226a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: Sum += I + 2; 7236a1f8ef8SChris Cotter 7246a1f8ef8SChris Cotter for (int I = 0, E = size(V); E != I; ++I) { 7256a1f8ef8SChris Cotter V[I] = 0; 7266a1f8ef8SChris Cotter } 7276a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 7286a1f8ef8SChris Cotter // CHECK-FIXES: for (int & I : V) 7296a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: I = 0; 7306a1f8ef8SChris Cotter 7316a1f8ef8SChris Cotter for (int I = 0, E = std::size(V); E != I; ++I) { 7326a1f8ef8SChris Cotter V[I] = 0; 7336a1f8ef8SChris Cotter } 7346a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 7356a1f8ef8SChris Cotter // CHECK-FIXES: for (int & I : V) 7366a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: I = 0; 7376a1f8ef8SChris Cotter 7386a1f8ef8SChris Cotter // Although 'length' might be a valid free function, only size() is standardized 7396a1f8ef8SChris Cotter for (int I = 0, E = length(V); E != I; ++I) { 7406a1f8ef8SChris Cotter printf("Fibonacci number is %d\n", V[I]); 7416a1f8ef8SChris Cotter Sum += V[I] + 2; 7426a1f8ef8SChris Cotter } 7436a1f8ef8SChris Cotter 7446a1f8ef8SChris Cotter dependent<Val> Vals; 7456a1f8ef8SChris Cotter for (int I = 0, E = size(Vals); E != I; ++I) { 7466a1f8ef8SChris Cotter Sum += Vals[I].X; 7476a1f8ef8SChris Cotter } 7486a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 7496a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & Val : Vals) 7506a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: Sum += Val.X; 75189a1d03eSRichard } 75289a1d03eSRichard 75389a1d03eSRichard // Ensure that 'const auto &' is used with containers of non-trivial types. 75489a1d03eSRichard void constness() { 75589a1d03eSRichard int Sum = 0; 75689a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 75789a1d03eSRichard printf("Fibonacci number is %d\n", Constv[I].X); 75889a1d03eSRichard Sum += Constv[I].X + 2; 75989a1d03eSRichard } 76089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 76189a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 76289a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 76389a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 76489a1d03eSRichard 76589a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 76689a1d03eSRichard printf("Fibonacci number is %d\n", Constv.at(I).X); 76789a1d03eSRichard Sum += Constv.at(I).X + 2; 76889a1d03eSRichard } 76989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 77089a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 77189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 77289a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 77389a1d03eSRichard 77489a1d03eSRichard for (int I = 0, E = Pconstv->size(); I < E; ++I) { 77589a1d03eSRichard printf("Fibonacci number is %d\n", Pconstv->at(I).X); 77689a1d03eSRichard Sum += Pconstv->at(I).X + 2; 77789a1d03eSRichard } 77889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 77989a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 78089a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 78189a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 78289a1d03eSRichard 78389a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 78489a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 78589a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 78689a1d03eSRichard // explicitly. 78789a1d03eSRichard for (int I = 0; I < Pconstv->size(); ++I) { 78889a1d03eSRichard printf("Fibonacci number is %d\n", (*Pconstv).at(I).X); 78989a1d03eSRichard Sum += (*Pconstv)[I].X + 2; 79089a1d03eSRichard } 79189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 79289a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 79389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 79489a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 79589a1d03eSRichard } 79689a1d03eSRichard 79789a1d03eSRichard void constRef(const dependent<int>& ConstVRef) { 79889a1d03eSRichard int sum = 0; 79989a1d03eSRichard // FIXME: This does not work with size_t (probably due to the implementation 80089a1d03eSRichard // of dependent); make dependent work exactly like a std container type. 80189a1d03eSRichard for (int I = 0; I < ConstVRef.size(); ++I) { 80289a1d03eSRichard sum += ConstVRef[I]; 80389a1d03eSRichard } 80489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 80589a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 80689a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 80789a1d03eSRichard 80889a1d03eSRichard for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { 80989a1d03eSRichard sum += *I; 81089a1d03eSRichard } 81189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 81289a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 81389a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 81489a1d03eSRichard } 81589a1d03eSRichard 81689a1d03eSRichard // Check for loops that don't mention containers. 81789a1d03eSRichard void noContainer() { 81889a1d03eSRichard for (auto I = 0; I < V.size(); ++I) { 81989a1d03eSRichard } 82089a1d03eSRichard 82189a1d03eSRichard for (auto I = 0; I < V.size(); ++I) 82289a1d03eSRichard ; 82389a1d03eSRichard } 82489a1d03eSRichard 82589a1d03eSRichard struct NoBeginEnd { 82689a1d03eSRichard unsigned size() const; 82789a1d03eSRichard unsigned& operator[](int); 82889a1d03eSRichard const unsigned& operator[](int) const; 82989a1d03eSRichard }; 83089a1d03eSRichard 83189a1d03eSRichard struct NoConstBeginEnd { 83289a1d03eSRichard NoConstBeginEnd(); 83389a1d03eSRichard unsigned size() const; 83489a1d03eSRichard unsigned* begin(); 83589a1d03eSRichard unsigned* end(); 83689a1d03eSRichard unsigned& operator[](int); 83789a1d03eSRichard const unsigned& operator[](int) const; 83889a1d03eSRichard }; 83989a1d03eSRichard 84089a1d03eSRichard struct ConstBeginEnd { 84189a1d03eSRichard ConstBeginEnd(); 84289a1d03eSRichard unsigned size() const; 84389a1d03eSRichard unsigned* begin() const; 84489a1d03eSRichard unsigned* end() const; 84589a1d03eSRichard unsigned& operator[](int); 84689a1d03eSRichard const unsigned& operator[](int) const; 84789a1d03eSRichard }; 84889a1d03eSRichard 84989a1d03eSRichard // Shouldn't transform pseudo-array uses if the container doesn't provide 85089a1d03eSRichard // begin() and end() of the right const-ness. 85189a1d03eSRichard void NoBeginEndTest() { 85289a1d03eSRichard NoBeginEnd NBE; 85389a1d03eSRichard for (unsigned I = 0, E = NBE.size(); I < E; ++I) 85489a1d03eSRichard printf("%d\n", NBE[I]); 85589a1d03eSRichard 85689a1d03eSRichard const NoConstBeginEnd Const_NCBE; 85789a1d03eSRichard for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I) 85889a1d03eSRichard printf("%d\n", Const_NCBE[I]); 85989a1d03eSRichard 86089a1d03eSRichard ConstBeginEnd CBE; 86189a1d03eSRichard for (unsigned I = 0, E = CBE.size(); I < E; ++I) 86289a1d03eSRichard printf("%d\n", CBE[I]); 86389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 86489a1d03eSRichard // CHECK-FIXES: for (unsigned int I : CBE) 86589a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 86689a1d03eSRichard 86789a1d03eSRichard const ConstBeginEnd Const_CBE; 86889a1d03eSRichard for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I) 86989a1d03eSRichard printf("%d\n", Const_CBE[I]); 87089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 87189a1d03eSRichard // CHECK-FIXES: for (unsigned int I : Const_CBE) 87289a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 87389a1d03eSRichard } 87489a1d03eSRichard 87589a1d03eSRichard struct DerefByValue { 87689a1d03eSRichard DerefByValue(); 87789a1d03eSRichard struct iter { unsigned operator*(); }; 87889a1d03eSRichard unsigned size() const; 87989a1d03eSRichard iter begin(); 88089a1d03eSRichard iter end(); 88189a1d03eSRichard unsigned operator[](int); 88289a1d03eSRichard }; 88389a1d03eSRichard 88489a1d03eSRichard void derefByValueTest() { 88589a1d03eSRichard DerefByValue DBV; 88689a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 88789a1d03eSRichard printf("%d\n", DBV[I]); 88889a1d03eSRichard } 88989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 89089a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 89189a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 89289a1d03eSRichard 89389a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 89489a1d03eSRichard auto f = [DBV, I]() {}; 89589a1d03eSRichard printf("%d\n", DBV[I]); 89689a1d03eSRichard } 89789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 89889a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 89989a1d03eSRichard // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; 90089a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 90189a1d03eSRichard } 90289a1d03eSRichard 90389a1d03eSRichard void fundamentalTypesTest() { 90489a1d03eSRichard const int N = 10; 90589a1d03eSRichard bool Bools[N]; 90689a1d03eSRichard for (int i = 0; i < N; ++i) 90789a1d03eSRichard printf("%d", Bools[i]); 90889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 90989a1d03eSRichard // CHECK-FIXES: for (bool Bool : Bools) 91089a1d03eSRichard 91189a1d03eSRichard int Ints[N]; 91289a1d03eSRichard unsigned short int Shorts[N]; 91389a1d03eSRichard for (int i = 0; i < N; ++i) 91489a1d03eSRichard printf("%d", Shorts[i]); 91589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 91689a1d03eSRichard // CHECK-FIXES: for (unsigned short Short : Shorts) 91789a1d03eSRichard 91889a1d03eSRichard signed long Longs[N]; 91989a1d03eSRichard for (int i = 0; i < N; ++i) 92089a1d03eSRichard printf("%d", Longs[i]); 92189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 92289a1d03eSRichard // CHECK-FIXES: for (long Long : Longs) 92389a1d03eSRichard 92489a1d03eSRichard long long int LongLongs[N]; 92589a1d03eSRichard for (int i = 0; i < N; ++i) 92689a1d03eSRichard printf("%d", LongLongs[i]); 92789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 92889a1d03eSRichard // CHECK-FIXES: for (long long LongLong : LongLongs) 92989a1d03eSRichard 93089a1d03eSRichard char Chars[N]; 93189a1d03eSRichard for (int i = 0; i < N; ++i) 93289a1d03eSRichard printf("%d", Chars[i]); 93389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 93489a1d03eSRichard // CHECK-FIXES: for (char Char : Chars) 93589a1d03eSRichard 93689a1d03eSRichard wchar_t WChars[N]; 93789a1d03eSRichard for (int i = 0; i < N; ++i) 93889a1d03eSRichard printf("%d", WChars[i]); 93989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 94089a1d03eSRichard // CHECK-FIXES: for (wchar_t WChar : WChars) 94189a1d03eSRichard 94289a1d03eSRichard float Floats[N]; 94389a1d03eSRichard for (int i = 0; i < N; ++i) 94489a1d03eSRichard printf("%d", Floats[i]); 94589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 94689a1d03eSRichard // CHECK-FIXES: for (float Float : Floats) 94789a1d03eSRichard 94889a1d03eSRichard double Doubles[N]; 94989a1d03eSRichard for (int i = 0; i < N; ++i) 95089a1d03eSRichard printf("%d", Doubles[i]); 95189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 95289a1d03eSRichard // CHECK-FIXES: for (double Double : Doubles) 95389a1d03eSRichard } 95489a1d03eSRichard 9555ae5af1dSCongcong Cai template <unsigned p> void _dependenceArrayTest() { 9565ae5af1dSCongcong Cai unsigned test[3][p]; 9575ae5af1dSCongcong Cai for (unsigned i = 0; i < p; ++i) 9585ae5af1dSCongcong Cai for (unsigned j = 0; j < 3; ++j) 9595ae5af1dSCongcong Cai printf("%d", test[j][i]); 9605ae5af1dSCongcong Cai // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 9615ae5af1dSCongcong Cai // CHECK-FIXES: (auto & j : test) 9625ae5af1dSCongcong Cai // CHECK-FIXES: printf("%d", j[i]); 9635ae5af1dSCongcong Cai } 9645ae5af1dSCongcong Cai void dependenceArrayTest() { 9655ae5af1dSCongcong Cai _dependenceArrayTest<1>(); 9665ae5af1dSCongcong Cai _dependenceArrayTest<2>(); 9675ae5af1dSCongcong Cai } 9685ae5af1dSCongcong Cai 96989a1d03eSRichard } // namespace PseudoArray 970296fbee5SPiotr Zegar 971296fbee5SPiotr Zegar namespace PR78381 { 972296fbee5SPiotr Zegar struct blocked_range { 973296fbee5SPiotr Zegar int begin() const; 974296fbee5SPiotr Zegar int end() const; 975296fbee5SPiotr Zegar }; 976296fbee5SPiotr Zegar 977296fbee5SPiotr Zegar void test() { 978296fbee5SPiotr Zegar blocked_range r; 979296fbee5SPiotr Zegar for (auto i = r.begin(); i!=r.end(); ++i) { 980296fbee5SPiotr Zegar } 981296fbee5SPiotr Zegar } 982296fbee5SPiotr Zegar } 983*e984d11dSCongcong Cai 984*e984d11dSCongcong Cai namespace GH109083 { 985*e984d11dSCongcong Cai void test() { 986*e984d11dSCongcong Cai const int N = 6; 987*e984d11dSCongcong Cai int Arr[N] = {1, 2, 3, 4, 5, 6}; 988*e984d11dSCongcong Cai 989*e984d11dSCongcong Cai for (int I = 0; I < N; ++I) { 990*e984d11dSCongcong Cai auto V = [T = Arr[I]]() {}; 991*e984d11dSCongcong Cai } 992*e984d11dSCongcong Cai // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] 993*e984d11dSCongcong Cai // CHECK-FIXES: for (int I : Arr) 994*e984d11dSCongcong Cai // CHECK-FIXES-NEXT: auto V = [T = I]() {}; 995*e984d11dSCongcong Cai for (int I = 0; I < N; ++I) { 996*e984d11dSCongcong Cai auto V = [T = 10 + Arr[I]]() {}; 997*e984d11dSCongcong Cai } 998*e984d11dSCongcong Cai // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] 999*e984d11dSCongcong Cai // CHECK-FIXES: for (int I : Arr) 1000*e984d11dSCongcong Cai // CHECK-FIXES-NEXT: auto V = [T = 10 + I]() {}; 1001*e984d11dSCongcong Cai 1002*e984d11dSCongcong Cai for (int I = 0; I < N; ++I) { 1003*e984d11dSCongcong Cai auto V = [T = I]() {}; 1004*e984d11dSCongcong Cai } 1005*e984d11dSCongcong Cai for (int I = 0; I < N; ++I) { 1006*e984d11dSCongcong Cai auto V = [T = I + 10]() {}; 1007*e984d11dSCongcong Cai } 1008*e984d11dSCongcong Cai } 1009*e984d11dSCongcong Cai } // namespace GH109083 1010