brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.0 KiB · 2f744eb Raw
1012 lines · cpp
1// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert2 3#include "structures.h"4 5namespace Array {6 7const int N = 6;8const int NMinusOne = N - 1;9int Arr[N] = {1, 2, 3, 4, 5, 6};10const int ConstArr[N] = {1, 2, 3, 4, 5, 6};11int (*PArr)[N] = &Arr;12 13void f() {14  int Sum = 0;15 16  for (int I = 0; I < N; ++I) {17    Sum += Arr[I];18    int K;19  }20  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert]21  // CHECK-FIXES: for (int I : Arr) {22  // CHECK-FIXES-NEXT: Sum += I;23  // CHECK-FIXES-NEXT: int K;24 25  for (int I = 0; I < N; ++I) {26    printf("Fibonacci number is %d\n", Arr[I]);27    Sum += Arr[I] + 2;28  }29  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead30  // CHECK-FIXES: for (int I : Arr) {31  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);32  // CHECK-FIXES-NEXT: Sum += I + 2;33 34  for (int I = 0; I < N; ++I) {35    int X = Arr[I];36    int Y = Arr[I] + 2;37  }38  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead39  // CHECK-FIXES: for (int I : Arr) {40  // CHECK-FIXES-NEXT: int X = I;41  // CHECK-FIXES-NEXT: int Y = I + 2;42 43  for (int I = 0; I < N; ++I) {44    int X = N;45    X = Arr[I];46  }47  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead48  // CHECK-FIXES: for (int I : Arr) {49  // CHECK-FIXES-NEXT: int X = N;50  // CHECK-FIXES-NEXT: X = I;51 52  for (int I = 0; I < N; ++I) {53    Arr[I] += 1;54  }55  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead56  // CHECK-FIXES: for (int & I : Arr) {57  // CHECK-FIXES-NEXT: I += 1;58 59  for (int I = 0; I < N; ++I) {60    int X = Arr[I] + 2;61    Arr[I]++;62  }63  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead64  // CHECK-FIXES: for (int & I : Arr) {65  // CHECK-FIXES-NEXT: int X = I + 2;66  // CHECK-FIXES-NEXT: I++;67 68  for (int I = 0; I < N; ++I) {69    Arr[I] = 4 + Arr[I];70  }71  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead72  // CHECK-FIXES: for (int & I : Arr) {73  // CHECK-FIXES-NEXT: I = 4 + I;74 75  for (int I = 0; I < NMinusOne + 1; ++I) {76    Sum += Arr[I];77  }78  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead79  // CHECK-FIXES: for (int I : Arr) {80  // CHECK-FIXES-NEXT: Sum += I;81 82  for (int I = 0; I < N; ++I) {83    printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);84    Sum += Arr[I] + 2;85  }86  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead87  // CHECK-FIXES: for (int & I : Arr) {88  // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);89  // CHECK-FIXES-NEXT: Sum += I + 2;90 91  int Matrix[N][12];92  unsigned size = 0;93  for (int I = 0; I < N; ++I) {94      size += sizeof(Matrix[I]);95      size += sizeof Matrix[I];96      size += sizeof((Matrix[I]));97  }98  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead99  // CHECK-FIXES: for (auto & I : Matrix) {100  // CHECK-FIXES-NEXT: size += sizeof(I);101  // CHECK-FIXES-NEXT: size += sizeof I;102  // CHECK-FIXES-NEXT: size += sizeof(I);103 104  Val Teas[N];105  for (int I = 0; I < N; ++I) {106    Teas[I].g();107  }108  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead109  // CHECK-FIXES: for (auto & Tea : Teas) {110  // CHECK-FIXES-NEXT: Tea.g();111 112  for (int I = 0; N > I; ++I) {113    printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);114    Sum += Arr[I] + 2;115  }116  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead117  // CHECK-FIXES: for (int & I : Arr) {118  // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);119  // CHECK-FIXES-NEXT: Sum += I + 2;120 121  for (int I = 0; N != I; ++I) {122    printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);123    Sum += Arr[I] + 2;124  }125  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead126  // CHECK-FIXES: for (int & I : Arr) {127  // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);128  // CHECK-FIXES-NEXT: Sum += I + 2;129 130  for (int I = 0; I != N; ++I) {131    printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);132    Sum += Arr[I] + 2;133  }134  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead135  // CHECK-FIXES: for (int & I : Arr) {136  // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);137  // CHECK-FIXES-NEXT: Sum += I + 2;138}139 140const int *constArray() {141  for (int I = 0; I < N; ++I) {142    printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);143  }144  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead145  // CHECK-FIXES: for (int I : ConstArr) {146  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I);147 148  const NonTriviallyCopyable NonCopy[N]{};149  for (int I = 0; I < N; ++I) {150    printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);151  }152  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead153  // CHECK-FIXES: for (const auto & I : NonCopy) {154  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);155 156  const TriviallyCopyableButBig Big[N]{};157  for (int I = 0; I < N; ++I) {158    printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);159  }160  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead161  // CHECK-FIXES: for (const auto & I : Big) {162  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);163 164  bool Something = false;165  for (int I = 0; I < N; ++I) {166    if (Something)167      return &ConstArr[I];168  }169  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead170  // CHECK-FIXES: for (const int & I : ConstArr) {171  // CHECK-FIXES-NEXT: if (Something)172  // CHECK-FIXES-NEXT: return &I;173 174  return nullptr;175}176 177struct HasArr {178  int Arr[N];179  Val ValArr[N];180  void implicitThis() {181    for (int I = 0; I < N; ++I) {182      printf("%d", Arr[I]);183    }184    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead185    // CHECK-FIXES: for (int I : Arr) {186    // CHECK-FIXES-NEXT: printf("%d", I);187 188    for (int I = 0; I < N; ++I) {189      printf("%d", ValArr[I].X);190    }191    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead192    // CHECK-FIXES: for (auto & I : ValArr) {193    // CHECK-FIXES-NEXT: printf("%d", I.X);194  }195 196  void explicitThis() {197    for (int I = 0; I < N; ++I) {198      printf("%d", this->Arr[I]);199    }200    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead201    // CHECK-FIXES: for (int I : this->Arr) {202    // CHECK-FIXES-NEXT: printf("%d", I);203 204    for (int I = 0; I < N; ++I) {205      printf("%d", this->ValArr[I].X);206    }207    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead208    // CHECK-FIXES: for (auto & I : this->ValArr) {209    // CHECK-FIXES-NEXT: printf("%d", I.X);210  }211};212 213struct HasIndirectArr {214  HasArr HA;215  void implicitThis() {216    for (int I = 0; I < N; ++I) {217      printf("%d", HA.Arr[I]);218    }219    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead220    // CHECK-FIXES: for (int I : HA.Arr) {221    // CHECK-FIXES-NEXT: printf("%d", I);222 223    for (int I = 0; I < N; ++I) {224      printf("%d", HA.ValArr[I].X);225    }226    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead227    // CHECK-FIXES: for (auto & I : HA.ValArr) {228    // CHECK-FIXES-NEXT: printf("%d", I.X);229  }230 231  void explicitThis() {232    for (int I = 0; I < N; ++I) {233      printf("%d", this->HA.Arr[I]);234    }235    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead236    // CHECK-FIXES: for (int I : this->HA.Arr) {237    // CHECK-FIXES-NEXT: printf("%d", I);238 239    for (int I = 0; I < N; ++I) {240      printf("%d", this->HA.ValArr[I].X);241    }242    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead243    // CHECK-FIXES: for (auto & I : this->HA.ValArr) {244    // CHECK-FIXES-NEXT: printf("%d", I.X);245  }246};247 248// Loops whose bounds are value-dependent should not be converted.249template <int N>250void dependentExprBound() {251  for (int I = 0; I < N; ++I)252    Arr[I] = 0;253}254template void dependentExprBound<20>();255 256void memberFunctionPointer() {257  Val V;258  void (Val::*mfpArr[N])(void) = {&Val::g};259  for (int I = 0; I < N; ++I)260    (V.*mfpArr[I])();261  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead262  // CHECK-FIXES: for (auto & I : mfpArr)263  // CHECK-FIXES-NEXT: (V.*I)();264 265  struct Foo {266    int (Val::*f)();267  } Foo[N];268 269  for (int I = 0; I < N; ++I)270    int R = (V.*(Foo[I].f))();271  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead272  // CHECK-FIXES: for (auto & I : Foo)273  // CHECK-FIXES-NEXT: int R = (V.*(I.f))();274 275}276 277} // namespace Array278 279namespace Iterator {280 281void f() {282  /// begin()/end() - based for loops here:283  T Tt;284  for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) {285    printf("I found %d\n", *It);286  }287  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead288  // CHECK-FIXES: for (int & It : Tt) {289  // CHECK-FIXES-NEXT: printf("I found %d\n", It);290 291  // Do not crash because of Qq.begin() converting. Q::iterator converts with a292  // conversion operator, which has no name, to Q::const_iterator.293  Q Qq;294  for (Q::const_iterator It = Qq.begin(), E = Qq.end(); It != E; ++It) {295    printf("I found %d\n", *It);296  }297  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead298  // CHECK-FIXES: for (int & It : Qq) {299  // CHECK-FIXES-NEXT: printf("I found %d\n", It);300 301  T *Pt;302  for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) {303    printf("I found %d\n", *It);304  }305  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead306  // CHECK-FIXES: for (int & It : *Pt) {307  // CHECK-FIXES-NEXT: printf("I found %d\n", It);308 309  S Ss;310  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {311    printf("s has value %d\n", (*It).X);312  }313  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead314  // CHECK-FIXES: for (auto & It : Ss) {315  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);316 317  S *Ps;318  for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {319    printf("s has value %d\n", (*It).X);320  }321  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead322  // CHECK-FIXES: for (auto & P : *Ps) {323  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);324 325  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {326    printf("s has value %d\n", (*It).X);327  }328  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead329  // CHECK-FIXES: for (auto It : Ss) {330  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);331 332  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {333    printf("s has value %d\n", It->X);334  }335  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead336  // CHECK-FIXES: for (auto & It : Ss) {337  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);338 339  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {340    It->X = 3;341  }342  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead343  // CHECK-FIXES: for (auto & It : Ss) {344  // CHECK-FIXES-NEXT: It.X = 3;345 346  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {347    (*It).X = 3;348  }349  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead350  // CHECK-FIXES: for (auto & It : Ss) {351  // CHECK-FIXES-NEXT: It.X = 3;352 353  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {354    It->nonConstFun(4, 5);355  }356  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead357  // CHECK-FIXES: for (auto & It : Ss) {358  // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);359 360  U Uu;361  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {362    printf("s has value %d\n", It->X);363  }364  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead365  // CHECK-FIXES: for (auto & It : Uu) {366  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);367 368  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {369    printf("s has value %d\n", (*It).X);370  }371  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead372  // CHECK-FIXES: for (auto & It : Uu) {373  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);374 375  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {376    Val* a = It.operator->();377  }378 379  U::iterator A;380  for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I)381    int K = A->X + I->X;382  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead383  // CHECK-FIXES: for (auto & I : Uu)384  // CHECK-FIXES-NEXT: int K = A->X + I.X;385 386  dependent<int> V;387  for (dependent<int>::iterator It = V.begin(), E = V.end();388       It != E; ++It) {389    printf("Fibonacci number is %d\n", *It);390  }391  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead392  // CHECK-FIXES: for (int & It : V) {393  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);394 395  for (dependent<int>::iterator It(V.begin()), E = V.end();396       It != E; ++It) {397    printf("Fibonacci number is %d\n", *It);398  }399  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead400  // CHECK-FIXES: for (int & It : V) {401  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);402 403  doublyDependent<int, int> Intmap;404  for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end();405       It != E; ++It) {406    printf("Intmap[%d] = %d", It->first, It->second);407  }408  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead409  // CHECK-FIXES: for (auto & It : Intmap) {410  // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second);411 412  // PtrSet's iterator dereferences by value so auto & can't be used.413  {414    PtrSet<int *> Val_int_ptrs;415    for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(),416                                 E = Val_int_ptrs.end();417         I != E; ++I) {418      (void) *I;419    }420    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead421    // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) {422  }423 424  // This container uses an iterator where the dereference type is a typedef of425  // a reference type. Make sure non-const auto & is still used. A failure here426  // means canonical types aren't being tested.427  {428    TypedefDerefContainer<int> Int_ptrs;429    for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(),430                                              E = Int_ptrs.end();431         I != E; ++I) {432      (void) *I;433    }434    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead435    // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) {436  }437 438  {439    // Iterators returning an rvalue reference should disqualify the loop from440    // transformation.441    RValueDerefContainer<int> Container;442    for (RValueDerefContainer<int>::iterator I = Container.begin(),443                                             E = Container.end();444         I != E; ++I) {445      (void) *I;446    }447  }448 449  dependent<Val *> Dpp;450  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {451    printf("%d\n", (**I).X);452  }453  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead454  // CHECK-FIXES: for (auto & I : Dpp) {455  // CHECK-FIXES-NEXT: printf("%d\n", (*I).X);456 457  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {458    printf("%d\n", (*I)->X);459  }460  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead461  // CHECK-FIXES: for (auto & I : Dpp) {462  // CHECK-FIXES-NEXT: printf("%d\n", I->X);463 464  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {465    printf("s0 has value %d\n", (*It).X);466  }467  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead468  // CHECK-FIXES: for (auto & It : Ss) {469  // CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X);470 471  for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) {472    printf("s1 has value %d\n", (*It).X);473  }474  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead475  // CHECK-FIXES: for (auto & It : Ss) {476  // CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X);477 478  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {479    printf("s2 has value %d\n", (*It).X);480  }481  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead482  // CHECK-FIXES: for (auto & It : *Ps) {483  // CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X);484 485  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {486    printf("s3 has value %d\n", (*It).X);487  }488  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead489  // CHECK-FIXES: for (auto & It : *Ps) {490  // CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X);491 492  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {493    printf("s4 has value %d\n", (*It).X);494  }495  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead496  // CHECK-FIXES: for (auto It : Ss) {497  // CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X);498}499 500// Tests to verify the proper use of auto where the init variable type and the501// initializer type differ or are mostly the same except for const qualifiers.502void different_type() {503  // Ss.begin() returns a type 'iterator' which is just a non-const pointer and504  // differs from const_iterator only on the const qualification.505  S Ss;506  for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {507    printf("s has value %d\n", (*It).X);508  }509  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead510  // CHECK-FIXES: for (auto It : Ss) {511  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);512 513  S *Ps;514  for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {515    printf("s has value %d\n", (*It).X);516  }517  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead518  // CHECK-FIXES: for (auto P : *Ps) {519  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);520 521  dependent<int> V;522  for (dependent<int>::const_iterator It = V.begin(), E = V.end();523       It != E; ++It) {524    printf("Fibonacci number is %d\n", *It);525  }526  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead527  // CHECK-FIXES: for (int It : V) {528  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);529 530  for (dependent<int>::const_iterator It(V.begin()), E = V.end();531       It != E; ++It) {532    printf("Fibonacci number is %d\n", *It);533  }534  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead535  // CHECK-FIXES: for (int It : V) {536  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);537}538 539// Tests to ensure that an implicit 'this' is picked up as the container.540// If member calls are made to 'this' within the loop, the transform becomes541// risky as these calls may affect state that affects the loop.542class C {543public:544  typedef MutableVal *iterator;545  typedef const MutableVal *const_iterator;546 547  iterator begin();548  iterator end();549  const_iterator begin() const;550  const_iterator end() const;551 552  void doSomething();553  void doSomething() const;554 555  void doLoop() {556    for (iterator I = begin(), E = end(); I != E; ++I)557      (void) *I;558    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead559    // CHECK-FIXES: for (auto & I : *this)560 561    for (iterator I = C::begin(), E = C::end(); I != E; ++I)562      (void) *I;563    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead564    // CHECK-FIXES: for (auto & I : *this)565 566    for (iterator I = begin(), E = end(); I != E; ++I) {567      (void) *I;568      doSomething();569    }570 571    for (iterator I = begin(); I != end(); ++I)572      (void) *I;573    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead574    // CHECK-FIXES: for (auto & I : *this)575 576    for (iterator I = begin(); I != end(); ++I) {577      (void) *I;578      doSomething();579    }580  }581 582  void doLoop() const {583    for (const_iterator I = begin(), E = end(); I != E; ++I)584      (void) *I;585    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead586    // CHECK-FIXES: for (auto I : *this)587 588    for (const_iterator I = C::begin(), E = C::end(); I != E; ++I)589      (void) *I;590    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead591    // CHECK-FIXES: for (auto I : *this)592 593    for (const_iterator I = begin(), E = end(); I != E; ++I) {594      (void) *I;595      doSomething();596    }597  }598};599 600class C2 {601public:602  typedef MutableVal *iterator;603 604  iterator begin() const;605  iterator end() const;606 607  void doLoop() {608    // The implicit 'this' will have an Implicit cast to const C2* wrapped609    // around it. Make sure the replacement still happens.610    for (iterator I = begin(), E = end(); I != E; ++I)611      (void) *I;612    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead613    // CHECK-FIXES: for (auto & I : *this)614  }615};616 617} // namespace Iterator618 619namespace PseudoArray {620 621const int N = 6;622dependent<int> V;623dependent<int> *Pv;624const dependent<NonTriviallyCopyable> Constv;625const dependent<NonTriviallyCopyable> *Pconstv;626 627transparent<dependent<int>> Cv;628dependent_derived<int> VD;629 630void f() {631  int Sum = 0;632  for (int I = 0, E = V.size(); I < E; ++I) {633    printf("Fibonacci number is %d\n", V[I]);634    Sum += V[I] + 2;635  }636  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead637  // CHECK-FIXES: for (int I : V) {638  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);639  // CHECK-FIXES-NEXT: Sum += I + 2;640 641  for (int I = 0, E = V.size(); I < E; ++I) {642    printf("Fibonacci number is %d\n", V.at(I));643    Sum += V.at(I) + 2;644  }645  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead646  // CHECK-FIXES: for (int I : V) {647  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);648  // CHECK-FIXES-NEXT: Sum += I + 2;649 650  for (int I = 0, E = Pv->size(); I < E; ++I) {651    printf("Fibonacci number is %d\n", Pv->at(I));652    Sum += Pv->at(I) + 2;653  }654  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead655  // CHECK-FIXES: for (int I : *Pv) {656  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);657  // CHECK-FIXES-NEXT: Sum += I + 2;658 659  // This test will fail if size() isn't called repeatedly, since it660  // returns unsigned int, and 0 is deduced to be signed int.661  // FIXME: Insert the necessary explicit conversion, or write out the types662  // explicitly.663  for (int I = 0; I < Pv->size(); ++I) {664    printf("Fibonacci number is %d\n", (*Pv).at(I));665    Sum += (*Pv)[I] + 2;666  }667  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead668  // CHECK-FIXES: for (int I : *Pv) {669  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);670  // CHECK-FIXES-NEXT: Sum += I + 2;671 672  for (int I = 0; I < Cv->size(); ++I) {673    printf("Fibonacci number is %d\n", Cv->at(I));674    Sum += Cv->at(I) + 2;675  }676  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead677  // CHECK-FIXES: for (int I : *Cv) {678  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);679  // CHECK-FIXES-NEXT: Sum += I + 2;680 681  for (int I = 0, E = V.size(); E > I; ++I) {682    printf("Fibonacci number is %d\n", V[I]);683    Sum += V[I] + 2;684  }685  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead686  // CHECK-FIXES: for (int I : V) {687  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);688  // CHECK-FIXES-NEXT: Sum += I + 2;689 690  for (int I = 0, E = V.size(); I != E; ++I) {691    printf("Fibonacci number is %d\n", V[I]);692    Sum += V[I] + 2;693  }694  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead695  // CHECK-FIXES: for (int I : V) {696  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);697  // CHECK-FIXES-NEXT: Sum += I + 2;698 699  for (int I = 0, E = V.size(); E != I; ++I) {700    printf("Fibonacci number is %d\n", V[I]);701    Sum += V[I] + 2;702  }703  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead704  // CHECK-FIXES: for (int I : V) {705  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);706  // CHECK-FIXES-NEXT: Sum += I + 2;707 708  for (int I = 0, E = VD.size(); E != I; ++I) {709    printf("Fibonacci number is %d\n", VD[I]);710    Sum += VD[I] + 2;711  }712  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead713  // CHECK-FIXES: for (int I : VD) {714  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);715  // CHECK-FIXES-NEXT: Sum += I + 2;716 717  for (int I = 0, E = size(V); E != I; ++I) {718    printf("Fibonacci number is %d\n", V[I]);719    Sum += V[I] + 2;720  }721  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead722  // CHECK-FIXES: for (int I : V) {723  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);724  // CHECK-FIXES-NEXT: Sum += I + 2;725 726  for (int I = 0, E = size(V); E != I; ++I) {727    V[I] = 0;728  }729  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead730  // CHECK-FIXES: for (int & I : V) {731  // CHECK-FIXES-NEXT: I = 0;732 733  for (int I = 0, E = std::size(V); E != I; ++I) {734    V[I] = 0;735  }736  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead737  // CHECK-FIXES: for (int & I : V) {738  // CHECK-FIXES-NEXT: I = 0;739 740  // Although 'length' might be a valid free function, only size() is standardized741  for (int I = 0, E = length(V); E != I; ++I) {742    printf("Fibonacci number is %d\n", V[I]);743    Sum += V[I] + 2;744  }745 746  dependent<Val> Vals;747  for (int I = 0, E = size(Vals); E != I; ++I) {748    Sum += Vals[I].X;749  }750  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead751  // CHECK-FIXES: for (auto & Val : Vals) {752  // CHECK-FIXES-NEXT: Sum += Val.X;753}754 755// Ensure that 'const auto &' is used with containers of non-trivial types.756void constness() {757  int Sum = 0;758  for (int I = 0, E = Constv.size(); I < E; ++I) {759    printf("Fibonacci number is %d\n", Constv[I].X);760    Sum += Constv[I].X + 2;761  }762  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead763  // CHECK-FIXES: for (const auto & I : Constv) {764  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);765  // CHECK-FIXES-NEXT: Sum += I.X + 2;766 767  for (int I = 0, E = Constv.size(); I < E; ++I) {768    printf("Fibonacci number is %d\n", Constv.at(I).X);769    Sum += Constv.at(I).X + 2;770  }771  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead772  // CHECK-FIXES: for (const auto & I : Constv) {773  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);774  // CHECK-FIXES-NEXT: Sum += I.X + 2;775 776  for (int I = 0, E = Pconstv->size(); I < E; ++I) {777    printf("Fibonacci number is %d\n", Pconstv->at(I).X);778    Sum += Pconstv->at(I).X + 2;779  }780  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead781  // CHECK-FIXES: for (const auto & I : *Pconstv) {782  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);783  // CHECK-FIXES-NEXT: Sum += I.X + 2;784 785  // This test will fail if size() isn't called repeatedly, since it786  // returns unsigned int, and 0 is deduced to be signed int.787  // FIXME: Insert the necessary explicit conversion, or write out the types788  // explicitly.789  for (int I = 0; I < Pconstv->size(); ++I) {790    printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);791    Sum += (*Pconstv)[I].X + 2;792  }793  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead794  // CHECK-FIXES: for (const auto & I : *Pconstv) {795  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);796  // CHECK-FIXES-NEXT: Sum += I.X + 2;797}798 799void constRef(const dependent<int>& ConstVRef) {800  int sum = 0;801  // FIXME: This does not work with size_t (probably due to the implementation802  // of dependent); make dependent work exactly like a std container type.803  for (int I = 0; I < ConstVRef.size(); ++I) {804    sum += ConstVRef[I];805  }806  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead807  // CHECK-FIXES: for (int I : ConstVRef) {808  // CHECK-FIXES-NEXT: sum += I;809 810  for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) {811    sum += *I;812  }813  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead814  // CHECK-FIXES: for (int I : ConstVRef) {815  // CHECK-FIXES-NEXT: sum += I;816}817 818// Check for loops that don't mention containers.819void noContainer() {820  for (auto I = 0; I < V.size(); ++I) {821  }822 823  for (auto I = 0; I < V.size(); ++I)824    ;825}826 827struct NoBeginEnd {828  unsigned size() const;829  unsigned& operator[](int);830  const unsigned& operator[](int) const;831};832 833struct NoConstBeginEnd {834  NoConstBeginEnd();835  unsigned size() const;836  unsigned* begin();837  unsigned* end();838  unsigned& operator[](int);839  const unsigned& operator[](int) const;840};841 842struct ConstBeginEnd {843  ConstBeginEnd();844  unsigned size() const;845  unsigned* begin() const;846  unsigned* end() const;847  unsigned& operator[](int);848  const unsigned& operator[](int) const;849};850 851// Shouldn't transform pseudo-array uses if the container doesn't provide852// begin() and end() of the right const-ness.853void NoBeginEndTest() {854  NoBeginEnd NBE;855  for (unsigned I = 0, E = NBE.size(); I < E; ++I)856    printf("%d\n", NBE[I]);857 858  const NoConstBeginEnd Const_NCBE;859  for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I)860    printf("%d\n", Const_NCBE[I]);861 862  ConstBeginEnd CBE;863  for (unsigned I = 0, E = CBE.size(); I < E; ++I)864    printf("%d\n", CBE[I]);865  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead866  // CHECK-FIXES: for (unsigned int I : CBE)867  // CHECK-FIXES-NEXT: printf("%d\n", I);868 869  const ConstBeginEnd Const_CBE;870  for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I)871    printf("%d\n", Const_CBE[I]);872  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead873  // CHECK-FIXES: for (unsigned int I : Const_CBE)874  // CHECK-FIXES-NEXT: printf("%d\n", I);875}876 877struct DerefByValue {878  DerefByValue();879  struct iter { unsigned operator*(); };880  unsigned size() const;881  iter begin();882  iter end();883  unsigned operator[](int);884};885 886void derefByValueTest() {887  DerefByValue DBV;888  for (unsigned I = 0, E = DBV.size(); I < E; ++I) {889    printf("%d\n", DBV[I]);890  }891  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead892  // CHECK-FIXES: for (unsigned int I : DBV) {893  // CHECK-FIXES-NEXT: printf("%d\n", I);894 895  for (unsigned I = 0, E = DBV.size(); I < E; ++I) {896    auto f = [DBV, I]() {};897    printf("%d\n", DBV[I]);898  }899  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead900  // CHECK-FIXES: for (unsigned int I : DBV) {901  // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {};902  // CHECK-FIXES-NEXT: printf("%d\n", I);903}904 905void fundamentalTypesTest() {906  const int N = 10;907  bool Bools[N];908  for (int i = 0; i < N; ++i)909    printf("%d", Bools[i]);910  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead911  // CHECK-FIXES: for (bool Bool : Bools)912 913  int Ints[N];914  unsigned short int Shorts[N];915  for (int i = 0; i < N; ++i)916    printf("%d", Shorts[i]);917  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead918  // CHECK-FIXES: for (unsigned short Short : Shorts)919 920  signed long Longs[N];921  for (int i = 0; i < N; ++i)922    printf("%d", Longs[i]);923  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead924  // CHECK-FIXES: for (long Long : Longs)925 926  long long int LongLongs[N];927  for (int i = 0; i < N; ++i)928    printf("%d", LongLongs[i]);929  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead930  // CHECK-FIXES: for (long long LongLong : LongLongs)931 932  char Chars[N];933  for (int i = 0; i < N; ++i)934    printf("%d", Chars[i]);935  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead936  // CHECK-FIXES: for (char Char : Chars)937 938  wchar_t WChars[N];939  for (int i = 0; i < N; ++i)940    printf("%d", WChars[i]);941  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead942  // CHECK-FIXES: for (wchar_t WChar : WChars)943 944  float Floats[N];945  for (int i = 0; i < N; ++i)946    printf("%d", Floats[i]);947  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead948  // CHECK-FIXES: for (float Float : Floats)949 950  double Doubles[N];951  for (int i = 0; i < N; ++i)952    printf("%d", Doubles[i]);953  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead954  // CHECK-FIXES: for (double Double : Doubles)955}956 957template <unsigned  p> void _dependenceArrayTest() {958  unsigned test[3][p];959  for (unsigned i = 0; i < p; ++i)960    for (unsigned j = 0; j < 3; ++j)961      printf("%d", test[j][i]);962  // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead963  // CHECK-FIXES: for (auto & j : test)964  // CHECK-FIXES: printf("%d", j[i]);965}966void dependenceArrayTest() {967  _dependenceArrayTest<1>();968  _dependenceArrayTest<2>();969}970 971} // namespace PseudoArray972 973namespace PR78381 {974  struct blocked_range {975    int begin() const;976    int end() const;977  };978 979  void test() {980    blocked_range r;981    for (auto i = r.begin(); i!=r.end(); ++i) {982    }983  }984}985 986namespace GH109083 {987void test() {988  const int N = 6;989  int Arr[N] = {1, 2, 3, 4, 5, 6};990 991  for (int I = 0; I < N; ++I) {992    auto V = [T = Arr[I]]() {};993  }994  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]995  // CHECK-FIXES: for (int I : Arr) {996  // CHECK-FIXES-NEXT: auto V = [T = I]() {};997  for (int I = 0; I < N; ++I) {998    auto V = [T = 10 + Arr[I]]() {};999  }1000  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]1001  // CHECK-FIXES: for (int I : Arr) {1002  // CHECK-FIXES-NEXT: auto V = [T = 10 + I]() {};1003 1004  for (int I = 0; I < N; ++I) {1005    auto V = [T = I]() {};1006  }1007  for (int I = 0; I < N; ++I) {1008    auto V = [T = I + 10]() {};1009  }1010}1011} // namespace GH1090831012