brintos

brintos / llvm-project-archived public Read only

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