brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · 59f472c Raw
361 lines · cpp
1// RUN: %check_clang_tidy %s modernize-loop-convert %t2 3struct Str {4  Str() = default;5  Str(const Str &) = default;6  void constMember(int) const;7  void nonConstMember(int);8  bool operator<(const Str &str) const;     // const operator.9  Str &operator=(const Str &str) = default; // non const operator.10};11 12// This class is non-trivially copyable because the copy-constructor and copy13// assignment take non-const references and are user-provided.14struct ModifiesRightSide {15  ModifiesRightSide() = default;16  ModifiesRightSide(ModifiesRightSide &);17  bool operator<(ModifiesRightSide &) const;18  ModifiesRightSide &operator=(ModifiesRightSide &);19};20 21template <typename T>22void copyArg(T);23 24template <typename T>25void nonConstRefArg(T &);26 27// If we define this as a template, the type is deduced to "T&",28// and "const (T&) &" is the same as "T& &", and this collapses to "T&".29void constRefArg(const Str &);30void constRefArg(const ModifiesRightSide &);31void constRefArg(const int &);32 33void foo();34 35const int N = 10;36Str Array[N], OtherStr;37ModifiesRightSide Right[N], OtherRight;38int Ints[N], OtherInt;39 40void memberFunctionsAndOperators() {41  // Calling const member functions or operator is a const usage.42  for (int I = 0; I < N; ++I) {43    Array[I].constMember(0);44  }45  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]46  // CHECK-FIXES: for (auto I : Array) {47  // CHECK-FIXES-NEXT: I.constMember(0);48 49  for (int I = 0; I < N; ++I) {50    if (Array[I] < OtherStr)51      foo();52  }53  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop54  // CHECK-FIXES: for (auto I : Array) {55  // CHECK-FIXES-NEXT: if (I < OtherStr)56  for (int I = 0; I < N; ++I) {57    if (Right[I] < OtherRight)58      foo();59  }60  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop61  // CHECK-FIXES: for (const auto & I : Right) {62  // CHECK-FIXES-NEXT: if (I < OtherRight)63 64  // Calling non-const member functions is not.65  for (int I = 0; I < N; ++I) {66    Array[I].nonConstMember(0);67  }68  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop69  // CHECK-FIXES: for (auto & I : Array) {70  // CHECK-FIXES-NEXT: I.nonConstMember(0);71 72  for (int I = 0; I < N; ++I) {73    Array[I] = OtherStr;74  }75  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop76  // CHECK-FIXES: for (auto & I : Array) {77  // CHECK-FIXES-NEXT: I = OtherStr;78 79  for (int I = 0; I < N; ++I) {80    Right[I] = OtherRight;81  }82  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop83  // CHECK-FIXES: for (auto & I : Right) {84  // CHECK-FIXES-NEXT: I = OtherRight;85}86 87void usedAsParameterToFunctionOrOperator() {88  // Copying is OK, as long as the copy constructor takes a const-reference.89  for (int I = 0; I < N; ++I) {90    copyArg(Array[I]);91  }92  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop93  // CHECK-FIXES: for (auto I : Array) {94  // CHECK-FIXES-NEXT: copyArg(I);95 96  for (int I = 0; I < N; ++I) {97    copyArg(Right[I]);98  }99  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop100  // CHECK-FIXES: for (auto & I : Right) {101  // CHECK-FIXES-NEXT: copyArg(I);102 103  // Using as a const reference argument is allowed.104  for (int I = 0; I < N; ++I) {105    constRefArg(Array[I]);106  }107  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop108  // CHECK-FIXES: for (auto I : Array) {109  // CHECK-FIXES-NEXT: constRefArg(I);110 111  for (int I = 0; I < N; ++I) {112    if (OtherStr < Array[I])113      foo();114  }115  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop116  // CHECK-FIXES: for (auto I : Array) {117  // CHECK-FIXES-NEXT: if (OtherStr < I)118 119  for (int I = 0; I < N; ++I) {120    constRefArg(Right[I]);121  }122  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop123  // CHECK-FIXES: for (const auto & I : Right) {124  // CHECK-FIXES-NEXT: constRefArg(I);125 126  // Using as a non-const reference is not.127  for (int I = 0; I < N; ++I) {128    nonConstRefArg(Array[I]);129  }130  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop131  // CHECK-FIXES: for (auto & I : Array) {132  // CHECK-FIXES-NEXT: nonConstRefArg(I);133  for (int I = 0; I < N; ++I) {134    nonConstRefArg(Right[I]);135  }136  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop137  // CHECK-FIXES: for (auto & I : Right) {138  // CHECK-FIXES-NEXT: nonConstRefArg(I);139  for (int I = 0; I < N; ++I) {140    if (OtherRight < Right[I])141      foo();142  }143  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop144  // CHECK-FIXES: for (auto & I : Right) {145  // CHECK-FIXES-NEXT: if (OtherRight < I)146}147 148void primitiveTypes() {149  // As argument to a function.150  for (int I = 0; I < N; ++I) {151    copyArg(Ints[I]);152  }153  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop154  // CHECK-FIXES: for (int Int : Ints) {155  // CHECK-FIXES-NEXT: copyArg(Int);156  for (int I = 0; I < N; ++I) {157    constRefArg(Ints[I]);158  }159  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop160  // CHECK-FIXES: for (int Int : Ints) {161  // CHECK-FIXES-NEXT: constRefArg(Int);162  for (int I = 0; I < N; ++I) {163    nonConstRefArg(Ints[I]);164  }165  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop166  // CHECK-FIXES: for (int & Int : Ints) {167  // CHECK-FIXES-NEXT: nonConstRefArg(Int);168 169  // Builtin operators.170  // Comparisons.171  for (int I = 0; I < N; ++I) {172    if (Ints[I] < N)173      foo();174  }175  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop176  // CHECK-FIXES: for (int Int : Ints) {177  // CHECK-FIXES-NEXT: if (Int < N)178 179  for (int I = 0; I < N; ++I) {180    if (N == Ints[I])181      foo();182  }183  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop184  // CHECK-FIXES: for (int Int : Ints) {185  // CHECK-FIXES-NEXT: if (N == Int)186 187  // Assignment.188  for (int I = 0; I < N; ++I) {189    Ints[I] = OtherInt;190  }191  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop192  // CHECK-FIXES: for (int & Int : Ints) {193  // CHECK-FIXES-NEXT: Int = OtherInt;194 195  for (int I = 0; I < N; ++I) {196    OtherInt = Ints[I];197  }198  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop199  // CHECK-FIXES: for (int Int : Ints) {200  // CHECK-FIXES-NEXT: OtherInt = Int;201 202  for (int I = 0; I < N; ++I) {203    OtherInt = Ints[I] = OtherInt;204  }205  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop206  // CHECK-FIXES: for (int & Int : Ints) {207  // CHECK-FIXES-NEXT: OtherInt = Int = OtherInt;208 209  // Arithmetic operations.210  for (int I = 0; I < N; ++I) {211    OtherInt += Ints[I];212  }213  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop214  // CHECK-FIXES: for (int Int : Ints) {215  // CHECK-FIXES-NEXT: OtherInt += Int;216 217  for (int I = 0; I < N; ++I) {218    Ints[I] += Ints[I];219  }220  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop221  // CHECK-FIXES: for (int & Int : Ints) {222  // CHECK-FIXES-NEXT: Int += Int;223 224  for (int I = 0; I < N; ++I) {225    int Res = 5 * (Ints[I] + 1) - Ints[I];226  }227  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop228  // CHECK-FIXES: for (int Int : Ints) {229  // CHECK-FIXES-NEXT: int Res = 5 * (Int + 1) - Int;230}231 232void takingReferences() {233  // We do it twice to prevent the check from thinking that they are aliases.234 235  // Class type.236  for (int I = 0; I < N; ++I) {237    Str &J = Array[I];238    Str &K = Array[I];239  }240  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop241  // CHECK-FIXES: for (auto & I : Array) {242  // CHECK-FIXES-NEXT: Str &J = I;243  // CHECK-FIXES-NEXT: Str &K = I;244  for (int I = 0; I < N; ++I) {245    const Str &J = Array[I];246    const Str &K = Array[I];247  }248  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop249  // CHECK-FIXES: for (auto I : Array) {250  // CHECK-FIXES-NEXT: const Str &J = I;251  // CHECK-FIXES-NEXT: const Str &K = I;252 253  // Primitive type.254  for (int I = 0; I < N; ++I) {255    int &J = Ints[I];256    int &K = Ints[I];257  }258  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop259  // CHECK-FIXES: for (int & Int : Ints) {260  // CHECK-FIXES-NEXT: int &J = Int;261  // CHECK-FIXES-NEXT: int &K = Int;262  for (int I = 0; I < N; ++I) {263    const int &J = Ints[I];264    const int &K = Ints[I];265  }266  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop267  // CHECK-FIXES: for (int Int : Ints) {268  // CHECK-FIXES-NEXT: const int &J = Int;269  // CHECK-FIXES-NEXT: const int &K = Int;270 271  // Aliases.272  for (int I = 0; I < N; ++I) {273    const Str &J = Array[I];274    (void)J;275  }276  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop277  // CHECK-FIXES: for (auto J : Array) {278  for (int I = 0; I < N; ++I) {279    Str &J = Array[I];280    (void)J;281  }282  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop283  // CHECK-FIXES: for (auto & J : Array) {284 285  for (int I = 0; I < N; ++I) {286    const int &J = Ints[I];287    (void)J;288  }289  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop290  // CHECK-FIXES: for (int J : Ints) {291 292  for (int I = 0; I < N; ++I) {293    int &J = Ints[I];294    (void)J;295  }296  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop297  // CHECK-FIXES: for (int & J : Ints) {298}299 300template <class T>301struct vector {302  unsigned size() const;303  const T &operator[](int) const;304  T &operator[](int);305  T *begin();306  T *end();307  const T *begin() const;308  const T *end() const;309};310 311// If the elements are already constant, we won't do any ImplicitCast to const.312void testContainerOfConstIents() {313  const int Ints[N]{};314  for (int I = 0; I < N; ++I) {315    OtherInt -= Ints[I];316  }317  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop318  // CHECK-FIXES: for (int Int : Ints) {319 320  vector<const Str> Strs;321  for (int I = 0; I < Strs.size(); ++I) {322    Strs[I].constMember(0);323    constRefArg(Strs[I]);324  }325  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop326  // CHECK-FIXES: for (auto Str : Strs) {327}328 329// When we are inside a const-qualified member functions, all the data members330// are implicitly set as const. As before, there won't be any ImplicitCast to331// const in their usages.332class TestInsideConstFunction {333  const static int N = 10;334  int Ints[N];335  Str Array[N];336  vector<int> V;337 338  void foo() const {339    for (int I = 0; I < N; ++I) {340      if (Ints[I])341        copyArg(Ints[I]);342    }343    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop344    // CHECK-FIXES: for (int Int : Ints) {345 346    for (int I = 0; I < N; ++I) {347      Array[I].constMember(0);348      constRefArg(Array[I]);349    }350    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop351    // CHECK-FIXES: for (auto I : Array) {352 353    for (int I = 0; I < V.size(); ++I) {354      if (V[I])355        copyArg(V[I]);356    }357    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop358    // CHECK-FIXES: for (int I : V) {359  }360};361