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); 44889a1d03eSRichard } 44989a1d03eSRichard 45089a1d03eSRichard // Tests to verify the proper use of auto where the init variable type and the 45189a1d03eSRichard // initializer type differ or are mostly the same except for const qualifiers. 45289a1d03eSRichard void different_type() { 45389a1d03eSRichard // Ss.begin() returns a type 'iterator' which is just a non-const pointer and 45489a1d03eSRichard // differs from const_iterator only on the const qualification. 45589a1d03eSRichard S Ss; 45689a1d03eSRichard for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 45789a1d03eSRichard printf("s has value %d\n", (*It).X); 45889a1d03eSRichard } 45989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 46089a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 46189a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 46289a1d03eSRichard 46389a1d03eSRichard S *Ps; 46489a1d03eSRichard for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 46589a1d03eSRichard printf("s has value %d\n", (*It).X); 46689a1d03eSRichard } 46789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 46889a1d03eSRichard // CHECK-FIXES: for (auto P : *Ps) 46989a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 47089a1d03eSRichard 47189a1d03eSRichard dependent<int> V; 47289a1d03eSRichard for (dependent<int>::const_iterator It = V.begin(), E = V.end(); 47389a1d03eSRichard It != E; ++It) { 47489a1d03eSRichard printf("Fibonacci number is %d\n", *It); 47589a1d03eSRichard } 47689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 47789a1d03eSRichard // CHECK-FIXES: for (int It : V) 47889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 47989a1d03eSRichard 48089a1d03eSRichard for (dependent<int>::const_iterator It(V.begin()), E = V.end(); 48189a1d03eSRichard It != E; ++It) { 48289a1d03eSRichard printf("Fibonacci number is %d\n", *It); 48389a1d03eSRichard } 48489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 48589a1d03eSRichard // CHECK-FIXES: for (int It : V) 48689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 48789a1d03eSRichard } 48889a1d03eSRichard 48989a1d03eSRichard // Tests to ensure that an implicit 'this' is picked up as the container. 49089a1d03eSRichard // If member calls are made to 'this' within the loop, the transform becomes 49189a1d03eSRichard // risky as these calls may affect state that affects the loop. 49289a1d03eSRichard class C { 49389a1d03eSRichard public: 49489a1d03eSRichard typedef MutableVal *iterator; 49589a1d03eSRichard typedef const MutableVal *const_iterator; 49689a1d03eSRichard 49789a1d03eSRichard iterator begin(); 49889a1d03eSRichard iterator end(); 49989a1d03eSRichard const_iterator begin() const; 50089a1d03eSRichard const_iterator end() const; 50189a1d03eSRichard 50289a1d03eSRichard void doSomething(); 50389a1d03eSRichard void doSomething() const; 50489a1d03eSRichard 50589a1d03eSRichard void doLoop() { 50689a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 50789a1d03eSRichard (void) *I; 50889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 50989a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 51089a1d03eSRichard 51189a1d03eSRichard for (iterator I = C::begin(), E = C::end(); I != E; ++I) 51289a1d03eSRichard (void) *I; 51389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 51489a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 51589a1d03eSRichard 51689a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) { 51789a1d03eSRichard (void) *I; 51889a1d03eSRichard doSomething(); 51989a1d03eSRichard } 52089a1d03eSRichard 52189a1d03eSRichard for (iterator I = begin(); I != end(); ++I) 52289a1d03eSRichard (void) *I; 52389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 52489a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 52589a1d03eSRichard 52689a1d03eSRichard for (iterator I = begin(); I != end(); ++I) { 52789a1d03eSRichard (void) *I; 52889a1d03eSRichard doSomething(); 52989a1d03eSRichard } 53089a1d03eSRichard } 53189a1d03eSRichard 53289a1d03eSRichard void doLoop() const { 53389a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) 53489a1d03eSRichard (void) *I; 53589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 53689a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 53789a1d03eSRichard 53889a1d03eSRichard for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) 53989a1d03eSRichard (void) *I; 54089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 54189a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 54289a1d03eSRichard 54389a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) { 54489a1d03eSRichard (void) *I; 54589a1d03eSRichard doSomething(); 54689a1d03eSRichard } 54789a1d03eSRichard } 54889a1d03eSRichard }; 54989a1d03eSRichard 55089a1d03eSRichard class C2 { 55189a1d03eSRichard public: 55289a1d03eSRichard typedef MutableVal *iterator; 55389a1d03eSRichard 55489a1d03eSRichard iterator begin() const; 55589a1d03eSRichard iterator end() const; 55689a1d03eSRichard 55789a1d03eSRichard void doLoop() { 55889a1d03eSRichard // The implicit 'this' will have an Implicit cast to const C2* wrapped 55989a1d03eSRichard // around it. Make sure the replacement still happens. 56089a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 56189a1d03eSRichard (void) *I; 56289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 56389a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 56489a1d03eSRichard } 56589a1d03eSRichard }; 56689a1d03eSRichard 56789a1d03eSRichard } // namespace Iterator 56889a1d03eSRichard 56989a1d03eSRichard namespace PseudoArray { 57089a1d03eSRichard 57189a1d03eSRichard const int N = 6; 57289a1d03eSRichard dependent<int> V; 57389a1d03eSRichard dependent<int> *Pv; 57489a1d03eSRichard const dependent<NonTriviallyCopyable> Constv; 57589a1d03eSRichard const dependent<NonTriviallyCopyable> *Pconstv; 57689a1d03eSRichard 57789a1d03eSRichard transparent<dependent<int>> Cv; 578*e4329520SChris Cotter dependent_derived<int> VD; 57989a1d03eSRichard 58089a1d03eSRichard void f() { 58189a1d03eSRichard int Sum = 0; 58289a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 58389a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 58489a1d03eSRichard Sum += V[I] + 2; 58589a1d03eSRichard } 58689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 58789a1d03eSRichard // CHECK-FIXES: for (int I : V) 58889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 58989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 59089a1d03eSRichard 59189a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 59289a1d03eSRichard printf("Fibonacci number is %d\n", V.at(I)); 59389a1d03eSRichard Sum += V.at(I) + 2; 59489a1d03eSRichard } 59589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 59689a1d03eSRichard // CHECK-FIXES: for (int I : V) 59789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 59889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 59989a1d03eSRichard 60089a1d03eSRichard for (int I = 0, E = Pv->size(); I < E; ++I) { 60189a1d03eSRichard printf("Fibonacci number is %d\n", Pv->at(I)); 60289a1d03eSRichard Sum += Pv->at(I) + 2; 60389a1d03eSRichard } 60489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 60589a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 60689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 60789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 60889a1d03eSRichard 60989a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 61089a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 61189a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 61289a1d03eSRichard // explicitly. 61389a1d03eSRichard for (int I = 0; I < Pv->size(); ++I) { 61489a1d03eSRichard printf("Fibonacci number is %d\n", (*Pv).at(I)); 61589a1d03eSRichard Sum += (*Pv)[I] + 2; 61689a1d03eSRichard } 61789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 61889a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 61989a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 62089a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 62189a1d03eSRichard 62289a1d03eSRichard for (int I = 0; I < Cv->size(); ++I) { 62389a1d03eSRichard printf("Fibonacci number is %d\n", Cv->at(I)); 62489a1d03eSRichard Sum += Cv->at(I) + 2; 62589a1d03eSRichard } 62689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 62789a1d03eSRichard // CHECK-FIXES: for (int I : *Cv) 62889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 62989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 63089a1d03eSRichard 63189a1d03eSRichard for (int I = 0, E = V.size(); E > I; ++I) { 63289a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 63389a1d03eSRichard Sum += V[I] + 2; 63489a1d03eSRichard } 63589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 63689a1d03eSRichard // CHECK-FIXES: for (int I : V) 63789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 63889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 63989a1d03eSRichard 64089a1d03eSRichard for (int I = 0, E = V.size(); I != E; ++I) { 64189a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 64289a1d03eSRichard Sum += V[I] + 2; 64389a1d03eSRichard } 64489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 64589a1d03eSRichard // CHECK-FIXES: for (int I : V) 64689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 64789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 64889a1d03eSRichard 64989a1d03eSRichard for (int I = 0, E = V.size(); E != I; ++I) { 65089a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 65189a1d03eSRichard Sum += V[I] + 2; 65289a1d03eSRichard } 65389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 65489a1d03eSRichard // CHECK-FIXES: for (int I : V) 65589a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 65689a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 657*e4329520SChris Cotter 658*e4329520SChris Cotter for (int I = 0, E = VD.size(); E != I; ++I) { 659*e4329520SChris Cotter printf("Fibonacci number is %d\n", VD[I]); 660*e4329520SChris Cotter Sum += VD[I] + 2; 661*e4329520SChris Cotter } 662*e4329520SChris Cotter // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 663*e4329520SChris Cotter // CHECK-FIXES: for (int I : VD) 664*e4329520SChris Cotter // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 665*e4329520SChris Cotter // CHECK-FIXES-NEXT: Sum += I + 2; 66689a1d03eSRichard } 66789a1d03eSRichard 66889a1d03eSRichard // Ensure that 'const auto &' is used with containers of non-trivial types. 66989a1d03eSRichard void constness() { 67089a1d03eSRichard int Sum = 0; 67189a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 67289a1d03eSRichard printf("Fibonacci number is %d\n", Constv[I].X); 67389a1d03eSRichard Sum += Constv[I].X + 2; 67489a1d03eSRichard } 67589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 67689a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 67789a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 67889a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 67989a1d03eSRichard 68089a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 68189a1d03eSRichard printf("Fibonacci number is %d\n", Constv.at(I).X); 68289a1d03eSRichard Sum += Constv.at(I).X + 2; 68389a1d03eSRichard } 68489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 68589a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 68689a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 68789a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 68889a1d03eSRichard 68989a1d03eSRichard for (int I = 0, E = Pconstv->size(); I < E; ++I) { 69089a1d03eSRichard printf("Fibonacci number is %d\n", Pconstv->at(I).X); 69189a1d03eSRichard Sum += Pconstv->at(I).X + 2; 69289a1d03eSRichard } 69389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 69489a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 69589a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 69689a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 69789a1d03eSRichard 69889a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 69989a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 70089a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 70189a1d03eSRichard // explicitly. 70289a1d03eSRichard for (int I = 0; I < Pconstv->size(); ++I) { 70389a1d03eSRichard printf("Fibonacci number is %d\n", (*Pconstv).at(I).X); 70489a1d03eSRichard Sum += (*Pconstv)[I].X + 2; 70589a1d03eSRichard } 70689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 70789a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 70889a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 70989a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 71089a1d03eSRichard } 71189a1d03eSRichard 71289a1d03eSRichard void constRef(const dependent<int>& ConstVRef) { 71389a1d03eSRichard int sum = 0; 71489a1d03eSRichard // FIXME: This does not work with size_t (probably due to the implementation 71589a1d03eSRichard // of dependent); make dependent work exactly like a std container type. 71689a1d03eSRichard for (int I = 0; I < ConstVRef.size(); ++I) { 71789a1d03eSRichard sum += ConstVRef[I]; 71889a1d03eSRichard } 71989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 72089a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 72189a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 72289a1d03eSRichard 72389a1d03eSRichard for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { 72489a1d03eSRichard sum += *I; 72589a1d03eSRichard } 72689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 72789a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 72889a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 72989a1d03eSRichard } 73089a1d03eSRichard 73189a1d03eSRichard // Check for loops that don't mention containers. 73289a1d03eSRichard void noContainer() { 73389a1d03eSRichard for (auto I = 0; I < V.size(); ++I) { 73489a1d03eSRichard } 73589a1d03eSRichard 73689a1d03eSRichard for (auto I = 0; I < V.size(); ++I) 73789a1d03eSRichard ; 73889a1d03eSRichard } 73989a1d03eSRichard 74089a1d03eSRichard struct NoBeginEnd { 74189a1d03eSRichard unsigned size() const; 74289a1d03eSRichard unsigned& operator[](int); 74389a1d03eSRichard const unsigned& operator[](int) const; 74489a1d03eSRichard }; 74589a1d03eSRichard 74689a1d03eSRichard struct NoConstBeginEnd { 74789a1d03eSRichard NoConstBeginEnd(); 74889a1d03eSRichard unsigned size() const; 74989a1d03eSRichard unsigned* begin(); 75089a1d03eSRichard unsigned* end(); 75189a1d03eSRichard unsigned& operator[](int); 75289a1d03eSRichard const unsigned& operator[](int) const; 75389a1d03eSRichard }; 75489a1d03eSRichard 75589a1d03eSRichard struct ConstBeginEnd { 75689a1d03eSRichard ConstBeginEnd(); 75789a1d03eSRichard unsigned size() const; 75889a1d03eSRichard unsigned* begin() const; 75989a1d03eSRichard unsigned* end() const; 76089a1d03eSRichard unsigned& operator[](int); 76189a1d03eSRichard const unsigned& operator[](int) const; 76289a1d03eSRichard }; 76389a1d03eSRichard 76489a1d03eSRichard // Shouldn't transform pseudo-array uses if the container doesn't provide 76589a1d03eSRichard // begin() and end() of the right const-ness. 76689a1d03eSRichard void NoBeginEndTest() { 76789a1d03eSRichard NoBeginEnd NBE; 76889a1d03eSRichard for (unsigned I = 0, E = NBE.size(); I < E; ++I) 76989a1d03eSRichard printf("%d\n", NBE[I]); 77089a1d03eSRichard 77189a1d03eSRichard const NoConstBeginEnd Const_NCBE; 77289a1d03eSRichard for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I) 77389a1d03eSRichard printf("%d\n", Const_NCBE[I]); 77489a1d03eSRichard 77589a1d03eSRichard ConstBeginEnd CBE; 77689a1d03eSRichard for (unsigned I = 0, E = CBE.size(); I < E; ++I) 77789a1d03eSRichard printf("%d\n", CBE[I]); 77889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 77989a1d03eSRichard // CHECK-FIXES: for (unsigned int I : CBE) 78089a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 78189a1d03eSRichard 78289a1d03eSRichard const ConstBeginEnd Const_CBE; 78389a1d03eSRichard for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I) 78489a1d03eSRichard printf("%d\n", Const_CBE[I]); 78589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 78689a1d03eSRichard // CHECK-FIXES: for (unsigned int I : Const_CBE) 78789a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 78889a1d03eSRichard } 78989a1d03eSRichard 79089a1d03eSRichard struct DerefByValue { 79189a1d03eSRichard DerefByValue(); 79289a1d03eSRichard struct iter { unsigned operator*(); }; 79389a1d03eSRichard unsigned size() const; 79489a1d03eSRichard iter begin(); 79589a1d03eSRichard iter end(); 79689a1d03eSRichard unsigned operator[](int); 79789a1d03eSRichard }; 79889a1d03eSRichard 79989a1d03eSRichard void derefByValueTest() { 80089a1d03eSRichard DerefByValue DBV; 80189a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 80289a1d03eSRichard printf("%d\n", DBV[I]); 80389a1d03eSRichard } 80489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 80589a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 80689a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 80789a1d03eSRichard 80889a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 80989a1d03eSRichard auto f = [DBV, I]() {}; 81089a1d03eSRichard printf("%d\n", DBV[I]); 81189a1d03eSRichard } 81289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 81389a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 81489a1d03eSRichard // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; 81589a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 81689a1d03eSRichard } 81789a1d03eSRichard 81889a1d03eSRichard void fundamentalTypesTest() { 81989a1d03eSRichard const int N = 10; 82089a1d03eSRichard bool Bools[N]; 82189a1d03eSRichard for (int i = 0; i < N; ++i) 82289a1d03eSRichard printf("%d", Bools[i]); 82389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 82489a1d03eSRichard // CHECK-FIXES: for (bool Bool : Bools) 82589a1d03eSRichard 82689a1d03eSRichard int Ints[N]; 82789a1d03eSRichard unsigned short int Shorts[N]; 82889a1d03eSRichard for (int i = 0; i < N; ++i) 82989a1d03eSRichard printf("%d", Shorts[i]); 83089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 83189a1d03eSRichard // CHECK-FIXES: for (unsigned short Short : Shorts) 83289a1d03eSRichard 83389a1d03eSRichard signed long Longs[N]; 83489a1d03eSRichard for (int i = 0; i < N; ++i) 83589a1d03eSRichard printf("%d", Longs[i]); 83689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 83789a1d03eSRichard // CHECK-FIXES: for (long Long : Longs) 83889a1d03eSRichard 83989a1d03eSRichard long long int LongLongs[N]; 84089a1d03eSRichard for (int i = 0; i < N; ++i) 84189a1d03eSRichard printf("%d", LongLongs[i]); 84289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 84389a1d03eSRichard // CHECK-FIXES: for (long long LongLong : LongLongs) 84489a1d03eSRichard 84589a1d03eSRichard char Chars[N]; 84689a1d03eSRichard for (int i = 0; i < N; ++i) 84789a1d03eSRichard printf("%d", Chars[i]); 84889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 84989a1d03eSRichard // CHECK-FIXES: for (char Char : Chars) 85089a1d03eSRichard 85189a1d03eSRichard wchar_t WChars[N]; 85289a1d03eSRichard for (int i = 0; i < N; ++i) 85389a1d03eSRichard printf("%d", WChars[i]); 85489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 85589a1d03eSRichard // CHECK-FIXES: for (wchar_t WChar : WChars) 85689a1d03eSRichard 85789a1d03eSRichard float Floats[N]; 85889a1d03eSRichard for (int i = 0; i < N; ++i) 85989a1d03eSRichard printf("%d", Floats[i]); 86089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 86189a1d03eSRichard // CHECK-FIXES: for (float Float : Floats) 86289a1d03eSRichard 86389a1d03eSRichard double Doubles[N]; 86489a1d03eSRichard for (int i = 0; i < N; ++i) 86589a1d03eSRichard printf("%d", Doubles[i]); 86689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 86789a1d03eSRichard // CHECK-FIXES: for (double Double : Doubles) 86889a1d03eSRichard } 86989a1d03eSRichard 87089a1d03eSRichard } // namespace PseudoArray 871