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 9189a1d03eSRichard Val Teas[N]; 9289a1d03eSRichard for (int I = 0; I < N; ++I) { 9389a1d03eSRichard Teas[I].g(); 9489a1d03eSRichard } 9589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 9689a1d03eSRichard // CHECK-FIXES: for (auto & Tea : Teas) 9789a1d03eSRichard // CHECK-FIXES-NEXT: Tea.g(); 9889a1d03eSRichard 9989a1d03eSRichard for (int I = 0; N > I; ++I) { 10089a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 10189a1d03eSRichard Sum += Arr[I] + 2; 10289a1d03eSRichard } 10389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 10489a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 10589a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 10689a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 10789a1d03eSRichard 10889a1d03eSRichard for (int I = 0; N != I; ++I) { 10989a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 11089a1d03eSRichard Sum += Arr[I] + 2; 11189a1d03eSRichard } 11289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 11389a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 11489a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 11589a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 11689a1d03eSRichard 11789a1d03eSRichard for (int I = 0; I != N; ++I) { 11889a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 11989a1d03eSRichard Sum += Arr[I] + 2; 12089a1d03eSRichard } 12189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 12289a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 12389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 12489a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 12589a1d03eSRichard } 12689a1d03eSRichard 12789a1d03eSRichard const int *constArray() { 12889a1d03eSRichard for (int I = 0; I < N; ++I) { 12989a1d03eSRichard printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]); 13089a1d03eSRichard } 13189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 13289a1d03eSRichard // CHECK-FIXES: for (int I : ConstArr) 13389a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I); 13489a1d03eSRichard 13589a1d03eSRichard const NonTriviallyCopyable NonCopy[N]{}; 13689a1d03eSRichard for (int I = 0; I < N; ++I) { 13789a1d03eSRichard printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X); 13889a1d03eSRichard } 13989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 14089a1d03eSRichard // CHECK-FIXES: for (const auto & I : NonCopy) 14189a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 14289a1d03eSRichard 14389a1d03eSRichard const TriviallyCopyableButBig Big[N]{}; 14489a1d03eSRichard for (int I = 0; I < N; ++I) { 14589a1d03eSRichard printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X); 14689a1d03eSRichard } 14789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 14889a1d03eSRichard // CHECK-FIXES: for (const auto & I : Big) 14989a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 15089a1d03eSRichard 15189a1d03eSRichard bool Something = false; 15289a1d03eSRichard for (int I = 0; I < N; ++I) { 15389a1d03eSRichard if (Something) 15489a1d03eSRichard return &ConstArr[I]; 15589a1d03eSRichard } 15689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 15789a1d03eSRichard // CHECK-FIXES: for (const int & I : ConstArr) 15889a1d03eSRichard // CHECK-FIXES-NEXT: if (Something) 15989a1d03eSRichard // CHECK-FIXES-NEXT: return &I; 16089a1d03eSRichard } 16189a1d03eSRichard 16289a1d03eSRichard struct HasArr { 16389a1d03eSRichard int Arr[N]; 16489a1d03eSRichard Val ValArr[N]; 16589a1d03eSRichard void implicitThis() { 16689a1d03eSRichard for (int I = 0; I < N; ++I) { 16789a1d03eSRichard printf("%d", Arr[I]); 16889a1d03eSRichard } 16989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 17089a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 17189a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 17289a1d03eSRichard 17389a1d03eSRichard for (int I = 0; I < N; ++I) { 17489a1d03eSRichard printf("%d", ValArr[I].X); 17589a1d03eSRichard } 17689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 17789a1d03eSRichard // CHECK-FIXES: for (auto & I : ValArr) 17889a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 17989a1d03eSRichard } 18089a1d03eSRichard 18189a1d03eSRichard void explicitThis() { 18289a1d03eSRichard for (int I = 0; I < N; ++I) { 18389a1d03eSRichard printf("%d", this->Arr[I]); 18489a1d03eSRichard } 18589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 18689a1d03eSRichard // CHECK-FIXES: for (int I : this->Arr) 18789a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 18889a1d03eSRichard 18989a1d03eSRichard for (int I = 0; I < N; ++I) { 19089a1d03eSRichard printf("%d", this->ValArr[I].X); 19189a1d03eSRichard } 19289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 19389a1d03eSRichard // CHECK-FIXES: for (auto & I : this->ValArr) 19489a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 19589a1d03eSRichard } 19689a1d03eSRichard }; 19789a1d03eSRichard 19889a1d03eSRichard struct HasIndirectArr { 19989a1d03eSRichard HasArr HA; 20089a1d03eSRichard void implicitThis() { 20189a1d03eSRichard for (int I = 0; I < N; ++I) { 20289a1d03eSRichard printf("%d", HA.Arr[I]); 20389a1d03eSRichard } 20489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 20589a1d03eSRichard // CHECK-FIXES: for (int I : HA.Arr) 20689a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 20789a1d03eSRichard 20889a1d03eSRichard for (int I = 0; I < N; ++I) { 20989a1d03eSRichard printf("%d", HA.ValArr[I].X); 21089a1d03eSRichard } 21189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 21289a1d03eSRichard // CHECK-FIXES: for (auto & I : HA.ValArr) 21389a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 21489a1d03eSRichard } 21589a1d03eSRichard 21689a1d03eSRichard void explicitThis() { 21789a1d03eSRichard for (int I = 0; I < N; ++I) { 21889a1d03eSRichard printf("%d", this->HA.Arr[I]); 21989a1d03eSRichard } 22089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 22189a1d03eSRichard // CHECK-FIXES: for (int I : this->HA.Arr) 22289a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 22389a1d03eSRichard 22489a1d03eSRichard for (int I = 0; I < N; ++I) { 22589a1d03eSRichard printf("%d", this->HA.ValArr[I].X); 22689a1d03eSRichard } 22789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 22889a1d03eSRichard // CHECK-FIXES: for (auto & I : this->HA.ValArr) 22989a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 23089a1d03eSRichard } 23189a1d03eSRichard }; 23289a1d03eSRichard 23389a1d03eSRichard // Loops whose bounds are value-dependent should not be converted. 23489a1d03eSRichard template <int N> 23589a1d03eSRichard void dependentExprBound() { 23689a1d03eSRichard for (int I = 0; I < N; ++I) 23789a1d03eSRichard Arr[I] = 0; 23889a1d03eSRichard } 23989a1d03eSRichard template void dependentExprBound<20>(); 24089a1d03eSRichard 24189a1d03eSRichard void memberFunctionPointer() { 24289a1d03eSRichard Val V; 24389a1d03eSRichard void (Val::*mfpArr[N])(void) = {&Val::g}; 24489a1d03eSRichard for (int I = 0; I < N; ++I) 24589a1d03eSRichard (V.*mfpArr[I])(); 24689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 24789a1d03eSRichard // CHECK-FIXES: for (auto & I : mfpArr) 24889a1d03eSRichard // CHECK-FIXES-NEXT: (V.*I)(); 24989a1d03eSRichard 25089a1d03eSRichard struct Foo { 25189a1d03eSRichard int (Val::*f)(); 25289a1d03eSRichard } Foo[N]; 25389a1d03eSRichard 25489a1d03eSRichard for (int I = 0; I < N; ++I) 25589a1d03eSRichard int R = (V.*(Foo[I].f))(); 25689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 25789a1d03eSRichard // CHECK-FIXES: for (auto & I : Foo) 25889a1d03eSRichard // CHECK-FIXES-NEXT: int R = (V.*(I.f))(); 25989a1d03eSRichard 26089a1d03eSRichard } 26189a1d03eSRichard 26289a1d03eSRichard } // namespace Array 26389a1d03eSRichard 26489a1d03eSRichard namespace Iterator { 26589a1d03eSRichard 26689a1d03eSRichard void f() { 26789a1d03eSRichard /// begin()/end() - based for loops here: 26889a1d03eSRichard T Tt; 26989a1d03eSRichard for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) { 27089a1d03eSRichard printf("I found %d\n", *It); 27189a1d03eSRichard } 27289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 27389a1d03eSRichard // CHECK-FIXES: for (int & It : Tt) 27489a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 27589a1d03eSRichard 27689a1d03eSRichard // Do not crash because of Qq.begin() converting. Q::iterator converts with a 27789a1d03eSRichard // conversion operator, which has no name, to Q::const_iterator. 27889a1d03eSRichard Q Qq; 27989a1d03eSRichard for (Q::const_iterator It = Qq.begin(), E = Qq.end(); It != E; ++It) { 28089a1d03eSRichard printf("I found %d\n", *It); 28189a1d03eSRichard } 28289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 28389a1d03eSRichard // CHECK-FIXES: for (int & It : Qq) 28489a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 28589a1d03eSRichard 28689a1d03eSRichard T *Pt; 28789a1d03eSRichard for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) { 28889a1d03eSRichard printf("I found %d\n", *It); 28989a1d03eSRichard } 29089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 29189a1d03eSRichard // CHECK-FIXES: for (int & It : *Pt) 29289a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 29389a1d03eSRichard 29489a1d03eSRichard S Ss; 29589a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 29689a1d03eSRichard printf("s has value %d\n", (*It).X); 29789a1d03eSRichard } 29889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 29989a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 30089a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 30189a1d03eSRichard 30289a1d03eSRichard S *Ps; 30389a1d03eSRichard for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 30489a1d03eSRichard printf("s has value %d\n", (*It).X); 30589a1d03eSRichard } 30689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 30789a1d03eSRichard // CHECK-FIXES: for (auto & P : *Ps) 30889a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 30989a1d03eSRichard 31089a1d03eSRichard for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) { 31189a1d03eSRichard printf("s has value %d\n", (*It).X); 31289a1d03eSRichard } 31389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 31489a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 31589a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 31689a1d03eSRichard 31789a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 31889a1d03eSRichard printf("s has value %d\n", It->X); 31989a1d03eSRichard } 32089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 32189a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 32289a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 32389a1d03eSRichard 32489a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 32589a1d03eSRichard It->X = 3; 32689a1d03eSRichard } 32789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 32889a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 32989a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 33089a1d03eSRichard 33189a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 33289a1d03eSRichard (*It).X = 3; 33389a1d03eSRichard } 33489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 33589a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 33689a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 33789a1d03eSRichard 33889a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 33989a1d03eSRichard It->nonConstFun(4, 5); 34089a1d03eSRichard } 34189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 34289a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 34389a1d03eSRichard // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); 34489a1d03eSRichard 34589a1d03eSRichard U Uu; 34689a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 34789a1d03eSRichard printf("s has value %d\n", It->X); 34889a1d03eSRichard } 34989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 35089a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 35189a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 35289a1d03eSRichard 35389a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 35489a1d03eSRichard printf("s has value %d\n", (*It).X); 35589a1d03eSRichard } 35689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 35789a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 35889a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 35989a1d03eSRichard 36089a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 36189a1d03eSRichard Val* a = It.operator->(); 36289a1d03eSRichard } 36389a1d03eSRichard 36489a1d03eSRichard U::iterator A; 36589a1d03eSRichard for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I) 36689a1d03eSRichard int K = A->X + I->X; 36789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 36889a1d03eSRichard // CHECK-FIXES: for (auto & I : Uu) 36989a1d03eSRichard // CHECK-FIXES-NEXT: int K = A->X + I.X; 37089a1d03eSRichard 37189a1d03eSRichard dependent<int> V; 37289a1d03eSRichard for (dependent<int>::iterator It = V.begin(), E = V.end(); 37389a1d03eSRichard It != E; ++It) { 37489a1d03eSRichard printf("Fibonacci number is %d\n", *It); 37589a1d03eSRichard } 37689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 37789a1d03eSRichard // CHECK-FIXES: for (int & It : V) 37889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 37989a1d03eSRichard 38089a1d03eSRichard for (dependent<int>::iterator It(V.begin()), E = V.end(); 38189a1d03eSRichard It != E; ++It) { 38289a1d03eSRichard printf("Fibonacci number is %d\n", *It); 38389a1d03eSRichard } 38489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 38589a1d03eSRichard // CHECK-FIXES: for (int & It : V) 38689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 38789a1d03eSRichard 38889a1d03eSRichard doublyDependent<int, int> Intmap; 38989a1d03eSRichard for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end(); 39089a1d03eSRichard It != E; ++It) { 39189a1d03eSRichard printf("Intmap[%d] = %d", It->first, It->second); 39289a1d03eSRichard } 39389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 39489a1d03eSRichard // CHECK-FIXES: for (auto & It : Intmap) 39589a1d03eSRichard // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second); 39689a1d03eSRichard 39789a1d03eSRichard // PtrSet's iterator dereferences by value so auto & can't be used. 39889a1d03eSRichard { 39989a1d03eSRichard PtrSet<int *> Val_int_ptrs; 40089a1d03eSRichard for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(), 40189a1d03eSRichard E = Val_int_ptrs.end(); 40289a1d03eSRichard I != E; ++I) { 40389a1d03eSRichard (void) *I; 40489a1d03eSRichard } 40589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 40689a1d03eSRichard // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) 40789a1d03eSRichard } 40889a1d03eSRichard 40989a1d03eSRichard // This container uses an iterator where the dereference type is a typedef of 41089a1d03eSRichard // a reference type. Make sure non-const auto & is still used. A failure here 41189a1d03eSRichard // means canonical types aren't being tested. 41289a1d03eSRichard { 41389a1d03eSRichard TypedefDerefContainer<int> Int_ptrs; 41489a1d03eSRichard for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(), 41589a1d03eSRichard E = Int_ptrs.end(); 41689a1d03eSRichard I != E; ++I) { 41789a1d03eSRichard (void) *I; 41889a1d03eSRichard } 41989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 42089a1d03eSRichard // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) 42189a1d03eSRichard } 42289a1d03eSRichard 42389a1d03eSRichard { 42489a1d03eSRichard // Iterators returning an rvalue reference should disqualify the loop from 42589a1d03eSRichard // transformation. 42689a1d03eSRichard RValueDerefContainer<int> Container; 42789a1d03eSRichard for (RValueDerefContainer<int>::iterator I = Container.begin(), 42889a1d03eSRichard E = Container.end(); 42989a1d03eSRichard I != E; ++I) { 43089a1d03eSRichard (void) *I; 43189a1d03eSRichard } 43289a1d03eSRichard } 43389a1d03eSRichard 43489a1d03eSRichard dependent<Val *> Dpp; 43589a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 43689a1d03eSRichard printf("%d\n", (**I).X); 43789a1d03eSRichard } 43889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 43989a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 44089a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", (*I).X); 44189a1d03eSRichard 44289a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 44389a1d03eSRichard printf("%d\n", (*I)->X); 44489a1d03eSRichard } 44589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 44689a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 44789a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I->X); 448*6a1f8ef8SChris Cotter 449*6a1f8ef8SChris Cotter for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) { 450*6a1f8ef8SChris Cotter printf("s0 has value %d\n", (*It).X); 451*6a1f8ef8SChris Cotter } 452*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 453*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : Ss) 454*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X); 455*6a1f8ef8SChris Cotter 456*6a1f8ef8SChris Cotter for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) { 457*6a1f8ef8SChris Cotter printf("s1 has value %d\n", (*It).X); 458*6a1f8ef8SChris Cotter } 459*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 460*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : Ss) 461*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X); 462*6a1f8ef8SChris Cotter 463*6a1f8ef8SChris Cotter for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) { 464*6a1f8ef8SChris Cotter printf("s2 has value %d\n", (*It).X); 465*6a1f8ef8SChris Cotter } 466*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 467*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : *Ps) 468*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X); 469*6a1f8ef8SChris Cotter 470*6a1f8ef8SChris Cotter for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) { 471*6a1f8ef8SChris Cotter printf("s3 has value %d\n", (*It).X); 472*6a1f8ef8SChris Cotter } 473*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 474*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & It : *Ps) 475*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X); 476*6a1f8ef8SChris Cotter 477*6a1f8ef8SChris Cotter for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) { 478*6a1f8ef8SChris Cotter printf("s4 has value %d\n", (*It).X); 479*6a1f8ef8SChris Cotter } 480*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 481*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto It : Ss) 482*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X); 48389a1d03eSRichard } 48489a1d03eSRichard 48589a1d03eSRichard // Tests to verify the proper use of auto where the init variable type and the 48689a1d03eSRichard // initializer type differ or are mostly the same except for const qualifiers. 48789a1d03eSRichard void different_type() { 48889a1d03eSRichard // Ss.begin() returns a type 'iterator' which is just a non-const pointer and 48989a1d03eSRichard // differs from const_iterator only on the const qualification. 49089a1d03eSRichard S Ss; 49189a1d03eSRichard for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 49289a1d03eSRichard printf("s has value %d\n", (*It).X); 49389a1d03eSRichard } 49489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 49589a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 49689a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 49789a1d03eSRichard 49889a1d03eSRichard S *Ps; 49989a1d03eSRichard for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 50089a1d03eSRichard printf("s has value %d\n", (*It).X); 50189a1d03eSRichard } 50289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 50389a1d03eSRichard // CHECK-FIXES: for (auto P : *Ps) 50489a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 50589a1d03eSRichard 50689a1d03eSRichard dependent<int> V; 50789a1d03eSRichard for (dependent<int>::const_iterator It = V.begin(), E = V.end(); 50889a1d03eSRichard It != E; ++It) { 50989a1d03eSRichard printf("Fibonacci number is %d\n", *It); 51089a1d03eSRichard } 51189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 51289a1d03eSRichard // CHECK-FIXES: for (int It : V) 51389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 51489a1d03eSRichard 51589a1d03eSRichard for (dependent<int>::const_iterator It(V.begin()), E = V.end(); 51689a1d03eSRichard It != E; ++It) { 51789a1d03eSRichard printf("Fibonacci number is %d\n", *It); 51889a1d03eSRichard } 51989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 52089a1d03eSRichard // CHECK-FIXES: for (int It : V) 52189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 52289a1d03eSRichard } 52389a1d03eSRichard 52489a1d03eSRichard // Tests to ensure that an implicit 'this' is picked up as the container. 52589a1d03eSRichard // If member calls are made to 'this' within the loop, the transform becomes 52689a1d03eSRichard // risky as these calls may affect state that affects the loop. 52789a1d03eSRichard class C { 52889a1d03eSRichard public: 52989a1d03eSRichard typedef MutableVal *iterator; 53089a1d03eSRichard typedef const MutableVal *const_iterator; 53189a1d03eSRichard 53289a1d03eSRichard iterator begin(); 53389a1d03eSRichard iterator end(); 53489a1d03eSRichard const_iterator begin() const; 53589a1d03eSRichard const_iterator end() const; 53689a1d03eSRichard 53789a1d03eSRichard void doSomething(); 53889a1d03eSRichard void doSomething() const; 53989a1d03eSRichard 54089a1d03eSRichard void doLoop() { 54189a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 54289a1d03eSRichard (void) *I; 54389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 54489a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 54589a1d03eSRichard 54689a1d03eSRichard for (iterator I = C::begin(), E = C::end(); I != E; ++I) 54789a1d03eSRichard (void) *I; 54889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 54989a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 55089a1d03eSRichard 55189a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) { 55289a1d03eSRichard (void) *I; 55389a1d03eSRichard doSomething(); 55489a1d03eSRichard } 55589a1d03eSRichard 55689a1d03eSRichard for (iterator I = begin(); I != end(); ++I) 55789a1d03eSRichard (void) *I; 55889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 55989a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 56089a1d03eSRichard 56189a1d03eSRichard for (iterator I = begin(); I != end(); ++I) { 56289a1d03eSRichard (void) *I; 56389a1d03eSRichard doSomething(); 56489a1d03eSRichard } 56589a1d03eSRichard } 56689a1d03eSRichard 56789a1d03eSRichard void doLoop() const { 56889a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) 56989a1d03eSRichard (void) *I; 57089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 57189a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 57289a1d03eSRichard 57389a1d03eSRichard for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) 57489a1d03eSRichard (void) *I; 57589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 57689a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 57789a1d03eSRichard 57889a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) { 57989a1d03eSRichard (void) *I; 58089a1d03eSRichard doSomething(); 58189a1d03eSRichard } 58289a1d03eSRichard } 58389a1d03eSRichard }; 58489a1d03eSRichard 58589a1d03eSRichard class C2 { 58689a1d03eSRichard public: 58789a1d03eSRichard typedef MutableVal *iterator; 58889a1d03eSRichard 58989a1d03eSRichard iterator begin() const; 59089a1d03eSRichard iterator end() const; 59189a1d03eSRichard 59289a1d03eSRichard void doLoop() { 59389a1d03eSRichard // The implicit 'this' will have an Implicit cast to const C2* wrapped 59489a1d03eSRichard // around it. Make sure the replacement still happens. 59589a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 59689a1d03eSRichard (void) *I; 59789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 59889a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 59989a1d03eSRichard } 60089a1d03eSRichard }; 60189a1d03eSRichard 60289a1d03eSRichard } // namespace Iterator 60389a1d03eSRichard 60489a1d03eSRichard namespace PseudoArray { 60589a1d03eSRichard 60689a1d03eSRichard const int N = 6; 60789a1d03eSRichard dependent<int> V; 60889a1d03eSRichard dependent<int> *Pv; 60989a1d03eSRichard const dependent<NonTriviallyCopyable> Constv; 61089a1d03eSRichard const dependent<NonTriviallyCopyable> *Pconstv; 61189a1d03eSRichard 61289a1d03eSRichard transparent<dependent<int>> Cv; 613e4329520SChris Cotter dependent_derived<int> VD; 61489a1d03eSRichard 61589a1d03eSRichard void f() { 61689a1d03eSRichard int Sum = 0; 61789a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 61889a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 61989a1d03eSRichard Sum += V[I] + 2; 62089a1d03eSRichard } 62189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 62289a1d03eSRichard // CHECK-FIXES: for (int I : V) 62389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 62489a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 62589a1d03eSRichard 62689a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 62789a1d03eSRichard printf("Fibonacci number is %d\n", V.at(I)); 62889a1d03eSRichard Sum += V.at(I) + 2; 62989a1d03eSRichard } 63089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 63189a1d03eSRichard // CHECK-FIXES: for (int I : V) 63289a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 63389a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 63489a1d03eSRichard 63589a1d03eSRichard for (int I = 0, E = Pv->size(); I < E; ++I) { 63689a1d03eSRichard printf("Fibonacci number is %d\n", Pv->at(I)); 63789a1d03eSRichard Sum += Pv->at(I) + 2; 63889a1d03eSRichard } 63989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 64089a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 64189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 64289a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 64389a1d03eSRichard 64489a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 64589a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 64689a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 64789a1d03eSRichard // explicitly. 64889a1d03eSRichard for (int I = 0; I < Pv->size(); ++I) { 64989a1d03eSRichard printf("Fibonacci number is %d\n", (*Pv).at(I)); 65089a1d03eSRichard Sum += (*Pv)[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 for (int I = 0; I < Cv->size(); ++I) { 65889a1d03eSRichard printf("Fibonacci number is %d\n", Cv->at(I)); 65989a1d03eSRichard Sum += Cv->at(I) + 2; 66089a1d03eSRichard } 66189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 66289a1d03eSRichard // CHECK-FIXES: for (int I : *Cv) 66389a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 66489a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 66589a1d03eSRichard 66689a1d03eSRichard for (int I = 0, E = V.size(); E > I; ++I) { 66789a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 66889a1d03eSRichard Sum += V[I] + 2; 66989a1d03eSRichard } 67089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 67189a1d03eSRichard // CHECK-FIXES: for (int I : V) 67289a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 67389a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 67489a1d03eSRichard 67589a1d03eSRichard for (int I = 0, E = V.size(); I != E; ++I) { 67689a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 67789a1d03eSRichard Sum += V[I] + 2; 67889a1d03eSRichard } 67989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 68089a1d03eSRichard // CHECK-FIXES: for (int I : V) 68189a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 68289a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 68389a1d03eSRichard 68489a1d03eSRichard for (int I = 0, E = V.size(); E != I; ++I) { 68589a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 68689a1d03eSRichard Sum += V[I] + 2; 68789a1d03eSRichard } 68889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 68989a1d03eSRichard // CHECK-FIXES: for (int I : V) 69089a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 69189a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 692e4329520SChris Cotter 693e4329520SChris Cotter for (int I = 0, E = VD.size(); E != I; ++I) { 694e4329520SChris Cotter printf("Fibonacci number is %d\n", VD[I]); 695e4329520SChris Cotter Sum += VD[I] + 2; 696e4329520SChris Cotter } 697e4329520SChris Cotter // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 698e4329520SChris Cotter // CHECK-FIXES: for (int I : VD) 699e4329520SChris Cotter // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 700e4329520SChris Cotter // CHECK-FIXES-NEXT: Sum += I + 2; 701*6a1f8ef8SChris Cotter 702*6a1f8ef8SChris Cotter for (int I = 0, E = size(V); E != I; ++I) { 703*6a1f8ef8SChris Cotter printf("Fibonacci number is %d\n", V[I]); 704*6a1f8ef8SChris Cotter Sum += V[I] + 2; 705*6a1f8ef8SChris Cotter } 706*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 707*6a1f8ef8SChris Cotter // CHECK-FIXES: for (int I : V) 708*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 709*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: Sum += I + 2; 710*6a1f8ef8SChris Cotter 711*6a1f8ef8SChris Cotter for (int I = 0, E = size(V); E != I; ++I) { 712*6a1f8ef8SChris Cotter V[I] = 0; 713*6a1f8ef8SChris Cotter } 714*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 715*6a1f8ef8SChris Cotter // CHECK-FIXES: for (int & I : V) 716*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: I = 0; 717*6a1f8ef8SChris Cotter 718*6a1f8ef8SChris Cotter for (int I = 0, E = std::size(V); E != I; ++I) { 719*6a1f8ef8SChris Cotter V[I] = 0; 720*6a1f8ef8SChris Cotter } 721*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 722*6a1f8ef8SChris Cotter // CHECK-FIXES: for (int & I : V) 723*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: I = 0; 724*6a1f8ef8SChris Cotter 725*6a1f8ef8SChris Cotter // Although 'length' might be a valid free function, only size() is standardized 726*6a1f8ef8SChris Cotter for (int I = 0, E = length(V); E != I; ++I) { 727*6a1f8ef8SChris Cotter printf("Fibonacci number is %d\n", V[I]); 728*6a1f8ef8SChris Cotter Sum += V[I] + 2; 729*6a1f8ef8SChris Cotter } 730*6a1f8ef8SChris Cotter 731*6a1f8ef8SChris Cotter dependent<Val> Vals; 732*6a1f8ef8SChris Cotter for (int I = 0, E = size(Vals); E != I; ++I) { 733*6a1f8ef8SChris Cotter Sum += Vals[I].X; 734*6a1f8ef8SChris Cotter } 735*6a1f8ef8SChris Cotter // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 736*6a1f8ef8SChris Cotter // CHECK-FIXES: for (auto & Val : Vals) 737*6a1f8ef8SChris Cotter // CHECK-FIXES-NEXT: Sum += Val.X; 73889a1d03eSRichard } 73989a1d03eSRichard 74089a1d03eSRichard // Ensure that 'const auto &' is used with containers of non-trivial types. 74189a1d03eSRichard void constness() { 74289a1d03eSRichard int Sum = 0; 74389a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 74489a1d03eSRichard printf("Fibonacci number is %d\n", Constv[I].X); 74589a1d03eSRichard Sum += Constv[I].X + 2; 74689a1d03eSRichard } 74789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 74889a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 74989a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 75089a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 75189a1d03eSRichard 75289a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 75389a1d03eSRichard printf("Fibonacci number is %d\n", Constv.at(I).X); 75489a1d03eSRichard Sum += Constv.at(I).X + 2; 75589a1d03eSRichard } 75689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 75789a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 75889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 75989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 76089a1d03eSRichard 76189a1d03eSRichard for (int I = 0, E = Pconstv->size(); I < E; ++I) { 76289a1d03eSRichard printf("Fibonacci number is %d\n", Pconstv->at(I).X); 76389a1d03eSRichard Sum += Pconstv->at(I).X + 2; 76489a1d03eSRichard } 76589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 76689a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 76789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 76889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 76989a1d03eSRichard 77089a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 77189a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 77289a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 77389a1d03eSRichard // explicitly. 77489a1d03eSRichard for (int I = 0; I < Pconstv->size(); ++I) { 77589a1d03eSRichard printf("Fibonacci number is %d\n", (*Pconstv).at(I).X); 77689a1d03eSRichard Sum += (*Pconstv)[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 78489a1d03eSRichard void constRef(const dependent<int>& ConstVRef) { 78589a1d03eSRichard int sum = 0; 78689a1d03eSRichard // FIXME: This does not work with size_t (probably due to the implementation 78789a1d03eSRichard // of dependent); make dependent work exactly like a std container type. 78889a1d03eSRichard for (int I = 0; I < ConstVRef.size(); ++I) { 78989a1d03eSRichard sum += ConstVRef[I]; 79089a1d03eSRichard } 79189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 79289a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 79389a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 79489a1d03eSRichard 79589a1d03eSRichard for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { 79689a1d03eSRichard sum += *I; 79789a1d03eSRichard } 79889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 79989a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 80089a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 80189a1d03eSRichard } 80289a1d03eSRichard 80389a1d03eSRichard // Check for loops that don't mention containers. 80489a1d03eSRichard void noContainer() { 80589a1d03eSRichard for (auto I = 0; I < V.size(); ++I) { 80689a1d03eSRichard } 80789a1d03eSRichard 80889a1d03eSRichard for (auto I = 0; I < V.size(); ++I) 80989a1d03eSRichard ; 81089a1d03eSRichard } 81189a1d03eSRichard 81289a1d03eSRichard struct NoBeginEnd { 81389a1d03eSRichard unsigned size() const; 81489a1d03eSRichard unsigned& operator[](int); 81589a1d03eSRichard const unsigned& operator[](int) const; 81689a1d03eSRichard }; 81789a1d03eSRichard 81889a1d03eSRichard struct NoConstBeginEnd { 81989a1d03eSRichard NoConstBeginEnd(); 82089a1d03eSRichard unsigned size() const; 82189a1d03eSRichard unsigned* begin(); 82289a1d03eSRichard unsigned* end(); 82389a1d03eSRichard unsigned& operator[](int); 82489a1d03eSRichard const unsigned& operator[](int) const; 82589a1d03eSRichard }; 82689a1d03eSRichard 82789a1d03eSRichard struct ConstBeginEnd { 82889a1d03eSRichard ConstBeginEnd(); 82989a1d03eSRichard unsigned size() const; 83089a1d03eSRichard unsigned* begin() const; 83189a1d03eSRichard unsigned* end() const; 83289a1d03eSRichard unsigned& operator[](int); 83389a1d03eSRichard const unsigned& operator[](int) const; 83489a1d03eSRichard }; 83589a1d03eSRichard 83689a1d03eSRichard // Shouldn't transform pseudo-array uses if the container doesn't provide 83789a1d03eSRichard // begin() and end() of the right const-ness. 83889a1d03eSRichard void NoBeginEndTest() { 83989a1d03eSRichard NoBeginEnd NBE; 84089a1d03eSRichard for (unsigned I = 0, E = NBE.size(); I < E; ++I) 84189a1d03eSRichard printf("%d\n", NBE[I]); 84289a1d03eSRichard 84389a1d03eSRichard const NoConstBeginEnd Const_NCBE; 84489a1d03eSRichard for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I) 84589a1d03eSRichard printf("%d\n", Const_NCBE[I]); 84689a1d03eSRichard 84789a1d03eSRichard ConstBeginEnd CBE; 84889a1d03eSRichard for (unsigned I = 0, E = CBE.size(); I < E; ++I) 84989a1d03eSRichard printf("%d\n", CBE[I]); 85089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 85189a1d03eSRichard // CHECK-FIXES: for (unsigned int I : CBE) 85289a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 85389a1d03eSRichard 85489a1d03eSRichard const ConstBeginEnd Const_CBE; 85589a1d03eSRichard for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I) 85689a1d03eSRichard printf("%d\n", Const_CBE[I]); 85789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 85889a1d03eSRichard // CHECK-FIXES: for (unsigned int I : Const_CBE) 85989a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 86089a1d03eSRichard } 86189a1d03eSRichard 86289a1d03eSRichard struct DerefByValue { 86389a1d03eSRichard DerefByValue(); 86489a1d03eSRichard struct iter { unsigned operator*(); }; 86589a1d03eSRichard unsigned size() const; 86689a1d03eSRichard iter begin(); 86789a1d03eSRichard iter end(); 86889a1d03eSRichard unsigned operator[](int); 86989a1d03eSRichard }; 87089a1d03eSRichard 87189a1d03eSRichard void derefByValueTest() { 87289a1d03eSRichard DerefByValue DBV; 87389a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 87489a1d03eSRichard printf("%d\n", DBV[I]); 87589a1d03eSRichard } 87689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 87789a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 87889a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 87989a1d03eSRichard 88089a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 88189a1d03eSRichard auto f = [DBV, I]() {}; 88289a1d03eSRichard printf("%d\n", DBV[I]); 88389a1d03eSRichard } 88489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 88589a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 88689a1d03eSRichard // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; 88789a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 88889a1d03eSRichard } 88989a1d03eSRichard 89089a1d03eSRichard void fundamentalTypesTest() { 89189a1d03eSRichard const int N = 10; 89289a1d03eSRichard bool Bools[N]; 89389a1d03eSRichard for (int i = 0; i < N; ++i) 89489a1d03eSRichard printf("%d", Bools[i]); 89589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 89689a1d03eSRichard // CHECK-FIXES: for (bool Bool : Bools) 89789a1d03eSRichard 89889a1d03eSRichard int Ints[N]; 89989a1d03eSRichard unsigned short int Shorts[N]; 90089a1d03eSRichard for (int i = 0; i < N; ++i) 90189a1d03eSRichard printf("%d", Shorts[i]); 90289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 90389a1d03eSRichard // CHECK-FIXES: for (unsigned short Short : Shorts) 90489a1d03eSRichard 90589a1d03eSRichard signed long Longs[N]; 90689a1d03eSRichard for (int i = 0; i < N; ++i) 90789a1d03eSRichard printf("%d", Longs[i]); 90889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 90989a1d03eSRichard // CHECK-FIXES: for (long Long : Longs) 91089a1d03eSRichard 91189a1d03eSRichard long long int LongLongs[N]; 91289a1d03eSRichard for (int i = 0; i < N; ++i) 91389a1d03eSRichard printf("%d", LongLongs[i]); 91489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 91589a1d03eSRichard // CHECK-FIXES: for (long long LongLong : LongLongs) 91689a1d03eSRichard 91789a1d03eSRichard char Chars[N]; 91889a1d03eSRichard for (int i = 0; i < N; ++i) 91989a1d03eSRichard printf("%d", Chars[i]); 92089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 92189a1d03eSRichard // CHECK-FIXES: for (char Char : Chars) 92289a1d03eSRichard 92389a1d03eSRichard wchar_t WChars[N]; 92489a1d03eSRichard for (int i = 0; i < N; ++i) 92589a1d03eSRichard printf("%d", WChars[i]); 92689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 92789a1d03eSRichard // CHECK-FIXES: for (wchar_t WChar : WChars) 92889a1d03eSRichard 92989a1d03eSRichard float Floats[N]; 93089a1d03eSRichard for (int i = 0; i < N; ++i) 93189a1d03eSRichard printf("%d", Floats[i]); 93289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 93389a1d03eSRichard // CHECK-FIXES: for (float Float : Floats) 93489a1d03eSRichard 93589a1d03eSRichard double Doubles[N]; 93689a1d03eSRichard for (int i = 0; i < N; ++i) 93789a1d03eSRichard printf("%d", Doubles[i]); 93889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 93989a1d03eSRichard // CHECK-FIXES: for (double Double : Doubles) 94089a1d03eSRichard } 94189a1d03eSRichard 94289a1d03eSRichard } // namespace PseudoArray 943