1 // RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert 2 3 #include "structures.h" 4 5 namespace Array { 6 7 const int N = 6; 8 const int NMinusOne = N - 1; 9 int Arr[N] = {1, 2, 3, 4, 5, 6}; 10 const int ConstArr[N] = {1, 2, 3, 4, 5, 6}; 11 int (*PArr)[N] = &Arr; 12 13 void 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 instead 30 // 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 instead 39 // 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 instead 48 // 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 instead 56 // 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 instead 64 // 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 instead 72 // 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 instead 79 // 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 instead 87 // 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 instead 99 // 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 instead 109 // 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 instead 117 // 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 instead 126 // 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 instead 135 // 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 140 const 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 instead 145 // 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 instead 153 // 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 instead 161 // 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 instead 170 // CHECK-FIXES: for (const int & I : ConstArr) 171 // CHECK-FIXES-NEXT: if (Something) 172 // CHECK-FIXES-NEXT: return &I; 173 } 174 175 struct HasArr { 176 int Arr[N]; 177 Val ValArr[N]; 178 void implicitThis() { 179 for (int I = 0; I < N; ++I) { 180 printf("%d", Arr[I]); 181 } 182 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 183 // CHECK-FIXES: for (int I : Arr) 184 // CHECK-FIXES-NEXT: printf("%d", I); 185 186 for (int I = 0; I < N; ++I) { 187 printf("%d", ValArr[I].X); 188 } 189 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 190 // CHECK-FIXES: for (auto & I : ValArr) 191 // CHECK-FIXES-NEXT: printf("%d", I.X); 192 } 193 194 void explicitThis() { 195 for (int I = 0; I < N; ++I) { 196 printf("%d", this->Arr[I]); 197 } 198 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 199 // CHECK-FIXES: for (int I : this->Arr) 200 // CHECK-FIXES-NEXT: printf("%d", I); 201 202 for (int I = 0; I < N; ++I) { 203 printf("%d", this->ValArr[I].X); 204 } 205 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 206 // CHECK-FIXES: for (auto & I : this->ValArr) 207 // CHECK-FIXES-NEXT: printf("%d", I.X); 208 } 209 }; 210 211 struct HasIndirectArr { 212 HasArr HA; 213 void implicitThis() { 214 for (int I = 0; I < N; ++I) { 215 printf("%d", HA.Arr[I]); 216 } 217 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 218 // CHECK-FIXES: for (int I : HA.Arr) 219 // CHECK-FIXES-NEXT: printf("%d", I); 220 221 for (int I = 0; I < N; ++I) { 222 printf("%d", HA.ValArr[I].X); 223 } 224 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 225 // CHECK-FIXES: for (auto & I : HA.ValArr) 226 // CHECK-FIXES-NEXT: printf("%d", I.X); 227 } 228 229 void explicitThis() { 230 for (int I = 0; I < N; ++I) { 231 printf("%d", this->HA.Arr[I]); 232 } 233 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 234 // CHECK-FIXES: for (int I : this->HA.Arr) 235 // CHECK-FIXES-NEXT: printf("%d", I); 236 237 for (int I = 0; I < N; ++I) { 238 printf("%d", this->HA.ValArr[I].X); 239 } 240 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 241 // CHECK-FIXES: for (auto & I : this->HA.ValArr) 242 // CHECK-FIXES-NEXT: printf("%d", I.X); 243 } 244 }; 245 246 // Loops whose bounds are value-dependent should not be converted. 247 template <int N> 248 void dependentExprBound() { 249 for (int I = 0; I < N; ++I) 250 Arr[I] = 0; 251 } 252 template void dependentExprBound<20>(); 253 254 void memberFunctionPointer() { 255 Val V; 256 void (Val::*mfpArr[N])(void) = {&Val::g}; 257 for (int I = 0; I < N; ++I) 258 (V.*mfpArr[I])(); 259 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 260 // CHECK-FIXES: for (auto & I : mfpArr) 261 // CHECK-FIXES-NEXT: (V.*I)(); 262 263 struct Foo { 264 int (Val::*f)(); 265 } Foo[N]; 266 267 for (int I = 0; I < N; ++I) 268 int R = (V.*(Foo[I].f))(); 269 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 270 // CHECK-FIXES: for (auto & I : Foo) 271 // CHECK-FIXES-NEXT: int R = (V.*(I.f))(); 272 273 } 274 275 } // namespace Array 276 277 namespace Iterator { 278 279 void f() { 280 /// begin()/end() - based for loops here: 281 T Tt; 282 for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) { 283 printf("I found %d\n", *It); 284 } 285 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 286 // CHECK-FIXES: for (int & It : Tt) 287 // CHECK-FIXES-NEXT: printf("I found %d\n", It); 288 289 // Do not crash because of Qq.begin() converting. Q::iterator converts with a 290 // conversion operator, which has no name, to Q::const_iterator. 291 Q Qq; 292 for (Q::const_iterator It = Qq.begin(), E = Qq.end(); It != E; ++It) { 293 printf("I found %d\n", *It); 294 } 295 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 296 // CHECK-FIXES: for (int & It : Qq) 297 // CHECK-FIXES-NEXT: printf("I found %d\n", It); 298 299 T *Pt; 300 for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) { 301 printf("I found %d\n", *It); 302 } 303 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 304 // CHECK-FIXES: for (int & It : *Pt) 305 // CHECK-FIXES-NEXT: printf("I found %d\n", It); 306 307 S Ss; 308 for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 309 printf("s has value %d\n", (*It).X); 310 } 311 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 312 // CHECK-FIXES: for (auto & It : Ss) 313 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 314 315 S *Ps; 316 for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 317 printf("s has value %d\n", (*It).X); 318 } 319 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 320 // CHECK-FIXES: for (auto & P : *Ps) 321 // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 322 323 for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) { 324 printf("s has value %d\n", (*It).X); 325 } 326 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 327 // CHECK-FIXES: for (auto It : Ss) 328 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 329 330 for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 331 printf("s has value %d\n", It->X); 332 } 333 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 334 // CHECK-FIXES: for (auto & It : Ss) 335 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 336 337 for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 338 It->X = 3; 339 } 340 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 341 // CHECK-FIXES: for (auto & It : Ss) 342 // CHECK-FIXES-NEXT: It.X = 3; 343 344 for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 345 (*It).X = 3; 346 } 347 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 348 // CHECK-FIXES: for (auto & It : Ss) 349 // CHECK-FIXES-NEXT: It.X = 3; 350 351 for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 352 It->nonConstFun(4, 5); 353 } 354 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 355 // CHECK-FIXES: for (auto & It : Ss) 356 // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); 357 358 U Uu; 359 for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 360 printf("s has value %d\n", It->X); 361 } 362 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 363 // CHECK-FIXES: for (auto & It : Uu) 364 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 365 366 for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 367 printf("s has value %d\n", (*It).X); 368 } 369 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 370 // CHECK-FIXES: for (auto & It : Uu) 371 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 372 373 for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 374 Val* a = It.operator->(); 375 } 376 377 U::iterator A; 378 for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I) 379 int K = A->X + I->X; 380 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 381 // CHECK-FIXES: for (auto & I : Uu) 382 // CHECK-FIXES-NEXT: int K = A->X + I.X; 383 384 dependent<int> V; 385 for (dependent<int>::iterator It = V.begin(), E = V.end(); 386 It != E; ++It) { 387 printf("Fibonacci number is %d\n", *It); 388 } 389 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 390 // CHECK-FIXES: for (int & It : V) 391 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 392 393 for (dependent<int>::iterator It(V.begin()), E = V.end(); 394 It != E; ++It) { 395 printf("Fibonacci number is %d\n", *It); 396 } 397 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 398 // CHECK-FIXES: for (int & It : V) 399 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 400 401 doublyDependent<int, int> Intmap; 402 for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end(); 403 It != E; ++It) { 404 printf("Intmap[%d] = %d", It->first, It->second); 405 } 406 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 407 // CHECK-FIXES: for (auto & It : Intmap) 408 // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second); 409 410 // PtrSet's iterator dereferences by value so auto & can't be used. 411 { 412 PtrSet<int *> Val_int_ptrs; 413 for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(), 414 E = Val_int_ptrs.end(); 415 I != E; ++I) { 416 (void) *I; 417 } 418 // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 419 // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) 420 } 421 422 // This container uses an iterator where the dereference type is a typedef of 423 // a reference type. Make sure non-const auto & is still used. A failure here 424 // means canonical types aren't being tested. 425 { 426 TypedefDerefContainer<int> Int_ptrs; 427 for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(), 428 E = Int_ptrs.end(); 429 I != E; ++I) { 430 (void) *I; 431 } 432 // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 433 // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) 434 } 435 436 { 437 // Iterators returning an rvalue reference should disqualify the loop from 438 // transformation. 439 RValueDerefContainer<int> Container; 440 for (RValueDerefContainer<int>::iterator I = Container.begin(), 441 E = Container.end(); 442 I != E; ++I) { 443 (void) *I; 444 } 445 } 446 447 dependent<Val *> Dpp; 448 for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 449 printf("%d\n", (**I).X); 450 } 451 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 452 // CHECK-FIXES: for (auto & I : Dpp) 453 // CHECK-FIXES-NEXT: printf("%d\n", (*I).X); 454 455 for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 456 printf("%d\n", (*I)->X); 457 } 458 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 459 // CHECK-FIXES: for (auto & I : Dpp) 460 // CHECK-FIXES-NEXT: printf("%d\n", I->X); 461 462 for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) { 463 printf("s0 has value %d\n", (*It).X); 464 } 465 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 466 // CHECK-FIXES: for (auto & It : Ss) 467 // CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X); 468 469 for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) { 470 printf("s1 has value %d\n", (*It).X); 471 } 472 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 473 // CHECK-FIXES: for (auto & It : Ss) 474 // CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X); 475 476 for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) { 477 printf("s2 has value %d\n", (*It).X); 478 } 479 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 480 // CHECK-FIXES: for (auto & It : *Ps) 481 // CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X); 482 483 for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) { 484 printf("s3 has value %d\n", (*It).X); 485 } 486 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 487 // CHECK-FIXES: for (auto & It : *Ps) 488 // CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X); 489 490 for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) { 491 printf("s4 has value %d\n", (*It).X); 492 } 493 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 494 // CHECK-FIXES: for (auto It : Ss) 495 // CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X); 496 } 497 498 // Tests to verify the proper use of auto where the init variable type and the 499 // initializer type differ or are mostly the same except for const qualifiers. 500 void different_type() { 501 // Ss.begin() returns a type 'iterator' which is just a non-const pointer and 502 // differs from const_iterator only on the const qualification. 503 S Ss; 504 for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 505 printf("s has value %d\n", (*It).X); 506 } 507 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 508 // CHECK-FIXES: for (auto It : Ss) 509 // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 510 511 S *Ps; 512 for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 513 printf("s has value %d\n", (*It).X); 514 } 515 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 516 // CHECK-FIXES: for (auto P : *Ps) 517 // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 518 519 dependent<int> V; 520 for (dependent<int>::const_iterator It = V.begin(), E = V.end(); 521 It != E; ++It) { 522 printf("Fibonacci number is %d\n", *It); 523 } 524 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 525 // CHECK-FIXES: for (int It : V) 526 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 527 528 for (dependent<int>::const_iterator It(V.begin()), E = V.end(); 529 It != E; ++It) { 530 printf("Fibonacci number is %d\n", *It); 531 } 532 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 533 // CHECK-FIXES: for (int It : V) 534 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 535 } 536 537 // Tests to ensure that an implicit 'this' is picked up as the container. 538 // If member calls are made to 'this' within the loop, the transform becomes 539 // risky as these calls may affect state that affects the loop. 540 class C { 541 public: 542 typedef MutableVal *iterator; 543 typedef const MutableVal *const_iterator; 544 545 iterator begin(); 546 iterator end(); 547 const_iterator begin() const; 548 const_iterator end() const; 549 550 void doSomething(); 551 void doSomething() const; 552 553 void doLoop() { 554 for (iterator I = begin(), E = end(); I != E; ++I) 555 (void) *I; 556 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 557 // CHECK-FIXES: for (auto & I : *this) 558 559 for (iterator I = C::begin(), E = C::end(); I != E; ++I) 560 (void) *I; 561 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 562 // CHECK-FIXES: for (auto & I : *this) 563 564 for (iterator I = begin(), E = end(); I != E; ++I) { 565 (void) *I; 566 doSomething(); 567 } 568 569 for (iterator I = begin(); I != end(); ++I) 570 (void) *I; 571 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 572 // CHECK-FIXES: for (auto & I : *this) 573 574 for (iterator I = begin(); I != end(); ++I) { 575 (void) *I; 576 doSomething(); 577 } 578 } 579 580 void doLoop() const { 581 for (const_iterator I = begin(), E = end(); I != E; ++I) 582 (void) *I; 583 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 584 // CHECK-FIXES: for (auto I : *this) 585 586 for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) 587 (void) *I; 588 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 589 // CHECK-FIXES: for (auto I : *this) 590 591 for (const_iterator I = begin(), E = end(); I != E; ++I) { 592 (void) *I; 593 doSomething(); 594 } 595 } 596 }; 597 598 class C2 { 599 public: 600 typedef MutableVal *iterator; 601 602 iterator begin() const; 603 iterator end() const; 604 605 void doLoop() { 606 // The implicit 'this' will have an Implicit cast to const C2* wrapped 607 // around it. Make sure the replacement still happens. 608 for (iterator I = begin(), E = end(); I != E; ++I) 609 (void) *I; 610 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 611 // CHECK-FIXES: for (auto & I : *this) 612 } 613 }; 614 615 } // namespace Iterator 616 617 namespace PseudoArray { 618 619 const int N = 6; 620 dependent<int> V; 621 dependent<int> *Pv; 622 const dependent<NonTriviallyCopyable> Constv; 623 const dependent<NonTriviallyCopyable> *Pconstv; 624 625 transparent<dependent<int>> Cv; 626 dependent_derived<int> VD; 627 628 void f() { 629 int Sum = 0; 630 for (int I = 0, E = V.size(); I < E; ++I) { 631 printf("Fibonacci number is %d\n", V[I]); 632 Sum += V[I] + 2; 633 } 634 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 635 // CHECK-FIXES: for (int I : V) 636 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 637 // CHECK-FIXES-NEXT: Sum += I + 2; 638 639 for (int I = 0, E = V.size(); I < E; ++I) { 640 printf("Fibonacci number is %d\n", V.at(I)); 641 Sum += V.at(I) + 2; 642 } 643 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 644 // CHECK-FIXES: for (int I : V) 645 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 646 // CHECK-FIXES-NEXT: Sum += I + 2; 647 648 for (int I = 0, E = Pv->size(); I < E; ++I) { 649 printf("Fibonacci number is %d\n", Pv->at(I)); 650 Sum += Pv->at(I) + 2; 651 } 652 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 653 // CHECK-FIXES: for (int I : *Pv) 654 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 655 // CHECK-FIXES-NEXT: Sum += I + 2; 656 657 // This test will fail if size() isn't called repeatedly, since it 658 // returns unsigned int, and 0 is deduced to be signed int. 659 // FIXME: Insert the necessary explicit conversion, or write out the types 660 // explicitly. 661 for (int I = 0; I < Pv->size(); ++I) { 662 printf("Fibonacci number is %d\n", (*Pv).at(I)); 663 Sum += (*Pv)[I] + 2; 664 } 665 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 666 // CHECK-FIXES: for (int I : *Pv) 667 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 668 // CHECK-FIXES-NEXT: Sum += I + 2; 669 670 for (int I = 0; I < Cv->size(); ++I) { 671 printf("Fibonacci number is %d\n", Cv->at(I)); 672 Sum += Cv->at(I) + 2; 673 } 674 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 675 // CHECK-FIXES: for (int I : *Cv) 676 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 677 // CHECK-FIXES-NEXT: Sum += I + 2; 678 679 for (int I = 0, E = V.size(); E > I; ++I) { 680 printf("Fibonacci number is %d\n", V[I]); 681 Sum += V[I] + 2; 682 } 683 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 684 // CHECK-FIXES: for (int I : V) 685 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 686 // CHECK-FIXES-NEXT: Sum += I + 2; 687 688 for (int I = 0, E = V.size(); I != E; ++I) { 689 printf("Fibonacci number is %d\n", V[I]); 690 Sum += V[I] + 2; 691 } 692 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 693 // CHECK-FIXES: for (int I : V) 694 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 695 // CHECK-FIXES-NEXT: Sum += I + 2; 696 697 for (int I = 0, E = V.size(); E != I; ++I) { 698 printf("Fibonacci number is %d\n", V[I]); 699 Sum += V[I] + 2; 700 } 701 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 702 // CHECK-FIXES: for (int I : V) 703 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 704 // CHECK-FIXES-NEXT: Sum += I + 2; 705 706 for (int I = 0, E = VD.size(); E != I; ++I) { 707 printf("Fibonacci number is %d\n", VD[I]); 708 Sum += VD[I] + 2; 709 } 710 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 711 // CHECK-FIXES: for (int I : VD) 712 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 713 // CHECK-FIXES-NEXT: Sum += I + 2; 714 715 for (int I = 0, E = size(V); E != I; ++I) { 716 printf("Fibonacci number is %d\n", V[I]); 717 Sum += V[I] + 2; 718 } 719 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 720 // CHECK-FIXES: for (int I : V) 721 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 722 // CHECK-FIXES-NEXT: Sum += I + 2; 723 724 for (int I = 0, E = size(V); E != I; ++I) { 725 V[I] = 0; 726 } 727 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 728 // CHECK-FIXES: for (int & I : V) 729 // CHECK-FIXES-NEXT: I = 0; 730 731 for (int I = 0, E = std::size(V); E != I; ++I) { 732 V[I] = 0; 733 } 734 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 735 // CHECK-FIXES: for (int & I : V) 736 // CHECK-FIXES-NEXT: I = 0; 737 738 // Although 'length' might be a valid free function, only size() is standardized 739 for (int I = 0, E = length(V); E != I; ++I) { 740 printf("Fibonacci number is %d\n", V[I]); 741 Sum += V[I] + 2; 742 } 743 744 dependent<Val> Vals; 745 for (int I = 0, E = size(Vals); E != I; ++I) { 746 Sum += Vals[I].X; 747 } 748 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 749 // CHECK-FIXES: for (auto & Val : Vals) 750 // CHECK-FIXES-NEXT: Sum += Val.X; 751 } 752 753 // Ensure that 'const auto &' is used with containers of non-trivial types. 754 void constness() { 755 int Sum = 0; 756 for (int I = 0, E = Constv.size(); I < E; ++I) { 757 printf("Fibonacci number is %d\n", Constv[I].X); 758 Sum += Constv[I].X + 2; 759 } 760 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 761 // CHECK-FIXES: for (const auto & I : Constv) 762 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 763 // CHECK-FIXES-NEXT: Sum += I.X + 2; 764 765 for (int I = 0, E = Constv.size(); I < E; ++I) { 766 printf("Fibonacci number is %d\n", Constv.at(I).X); 767 Sum += Constv.at(I).X + 2; 768 } 769 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 770 // CHECK-FIXES: for (const auto & I : Constv) 771 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 772 // CHECK-FIXES-NEXT: Sum += I.X + 2; 773 774 for (int I = 0, E = Pconstv->size(); I < E; ++I) { 775 printf("Fibonacci number is %d\n", Pconstv->at(I).X); 776 Sum += Pconstv->at(I).X + 2; 777 } 778 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 779 // CHECK-FIXES: for (const auto & I : *Pconstv) 780 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 781 // CHECK-FIXES-NEXT: Sum += I.X + 2; 782 783 // This test will fail if size() isn't called repeatedly, since it 784 // returns unsigned int, and 0 is deduced to be signed int. 785 // FIXME: Insert the necessary explicit conversion, or write out the types 786 // explicitly. 787 for (int I = 0; I < Pconstv->size(); ++I) { 788 printf("Fibonacci number is %d\n", (*Pconstv).at(I).X); 789 Sum += (*Pconstv)[I].X + 2; 790 } 791 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 792 // CHECK-FIXES: for (const auto & I : *Pconstv) 793 // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 794 // CHECK-FIXES-NEXT: Sum += I.X + 2; 795 } 796 797 void constRef(const dependent<int>& ConstVRef) { 798 int sum = 0; 799 // FIXME: This does not work with size_t (probably due to the implementation 800 // of dependent); make dependent work exactly like a std container type. 801 for (int I = 0; I < ConstVRef.size(); ++I) { 802 sum += ConstVRef[I]; 803 } 804 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 805 // CHECK-FIXES: for (int I : ConstVRef) 806 // CHECK-FIXES-NEXT: sum += I; 807 808 for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { 809 sum += *I; 810 } 811 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 812 // CHECK-FIXES: for (int I : ConstVRef) 813 // CHECK-FIXES-NEXT: sum += I; 814 } 815 816 // Check for loops that don't mention containers. 817 void noContainer() { 818 for (auto I = 0; I < V.size(); ++I) { 819 } 820 821 for (auto I = 0; I < V.size(); ++I) 822 ; 823 } 824 825 struct NoBeginEnd { 826 unsigned size() const; 827 unsigned& operator[](int); 828 const unsigned& operator[](int) const; 829 }; 830 831 struct NoConstBeginEnd { 832 NoConstBeginEnd(); 833 unsigned size() const; 834 unsigned* begin(); 835 unsigned* end(); 836 unsigned& operator[](int); 837 const unsigned& operator[](int) const; 838 }; 839 840 struct ConstBeginEnd { 841 ConstBeginEnd(); 842 unsigned size() const; 843 unsigned* begin() const; 844 unsigned* end() const; 845 unsigned& operator[](int); 846 const unsigned& operator[](int) const; 847 }; 848 849 // Shouldn't transform pseudo-array uses if the container doesn't provide 850 // begin() and end() of the right const-ness. 851 void NoBeginEndTest() { 852 NoBeginEnd NBE; 853 for (unsigned I = 0, E = NBE.size(); I < E; ++I) 854 printf("%d\n", NBE[I]); 855 856 const NoConstBeginEnd Const_NCBE; 857 for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I) 858 printf("%d\n", Const_NCBE[I]); 859 860 ConstBeginEnd CBE; 861 for (unsigned I = 0, E = CBE.size(); I < E; ++I) 862 printf("%d\n", CBE[I]); 863 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 864 // CHECK-FIXES: for (unsigned int I : CBE) 865 // CHECK-FIXES-NEXT: printf("%d\n", I); 866 867 const ConstBeginEnd Const_CBE; 868 for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I) 869 printf("%d\n", Const_CBE[I]); 870 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 871 // CHECK-FIXES: for (unsigned int I : Const_CBE) 872 // CHECK-FIXES-NEXT: printf("%d\n", I); 873 } 874 875 struct DerefByValue { 876 DerefByValue(); 877 struct iter { unsigned operator*(); }; 878 unsigned size() const; 879 iter begin(); 880 iter end(); 881 unsigned operator[](int); 882 }; 883 884 void derefByValueTest() { 885 DerefByValue DBV; 886 for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 887 printf("%d\n", DBV[I]); 888 } 889 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 890 // CHECK-FIXES: for (unsigned int I : DBV) 891 // CHECK-FIXES-NEXT: printf("%d\n", I); 892 893 for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 894 auto f = [DBV, I]() {}; 895 printf("%d\n", DBV[I]); 896 } 897 // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 898 // CHECK-FIXES: for (unsigned int I : DBV) 899 // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; 900 // CHECK-FIXES-NEXT: printf("%d\n", I); 901 } 902 903 void fundamentalTypesTest() { 904 const int N = 10; 905 bool Bools[N]; 906 for (int i = 0; i < N; ++i) 907 printf("%d", Bools[i]); 908 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 909 // CHECK-FIXES: for (bool Bool : Bools) 910 911 int Ints[N]; 912 unsigned short int Shorts[N]; 913 for (int i = 0; i < N; ++i) 914 printf("%d", Shorts[i]); 915 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 916 // CHECK-FIXES: for (unsigned short Short : Shorts) 917 918 signed long Longs[N]; 919 for (int i = 0; i < N; ++i) 920 printf("%d", Longs[i]); 921 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 922 // CHECK-FIXES: for (long Long : Longs) 923 924 long long int LongLongs[N]; 925 for (int i = 0; i < N; ++i) 926 printf("%d", LongLongs[i]); 927 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 928 // CHECK-FIXES: for (long long LongLong : LongLongs) 929 930 char Chars[N]; 931 for (int i = 0; i < N; ++i) 932 printf("%d", Chars[i]); 933 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 934 // CHECK-FIXES: for (char Char : Chars) 935 936 wchar_t WChars[N]; 937 for (int i = 0; i < N; ++i) 938 printf("%d", WChars[i]); 939 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 940 // CHECK-FIXES: for (wchar_t WChar : WChars) 941 942 float Floats[N]; 943 for (int i = 0; i < N; ++i) 944 printf("%d", Floats[i]); 945 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 946 // CHECK-FIXES: for (float Float : Floats) 947 948 double Doubles[N]; 949 for (int i = 0; i < N; ++i) 950 printf("%d", Doubles[i]); 951 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 952 // CHECK-FIXES: for (double Double : Doubles) 953 } 954 955 template <unsigned p> void _dependenceArrayTest() { 956 unsigned test[3][p]; 957 for (unsigned i = 0; i < p; ++i) 958 for (unsigned j = 0; j < 3; ++j) 959 printf("%d", test[j][i]); 960 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 961 // CHECK-FIXES: (auto & j : test) 962 // CHECK-FIXES: printf("%d", j[i]); 963 } 964 void dependenceArrayTest() { 965 _dependenceArrayTest<1>(); 966 _dependenceArrayTest<2>(); 967 } 968 969 } // namespace PseudoArray 970 971 namespace PR78381 { 972 struct blocked_range { 973 int begin() const; 974 int end() const; 975 }; 976 977 void test() { 978 blocked_range r; 979 for (auto i = r.begin(); i!=r.end(); ++i) { 980 } 981 } 982 } 983 984 namespace GH109083 { 985 void test() { 986 const int N = 6; 987 int Arr[N] = {1, 2, 3, 4, 5, 6}; 988 989 for (int I = 0; I < N; ++I) { 990 auto V = [T = Arr[I]]() {}; 991 } 992 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] 993 // CHECK-FIXES: for (int I : Arr) 994 // CHECK-FIXES-NEXT: auto V = [T = I]() {}; 995 for (int I = 0; I < N; ++I) { 996 auto V = [T = 10 + Arr[I]]() {}; 997 } 998 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] 999 // CHECK-FIXES: for (int I : Arr) 1000 // CHECK-FIXES-NEXT: auto V = [T = 10 + I]() {}; 1001 1002 for (int I = 0; I < N; ++I) { 1003 auto V = [T = I]() {}; 1004 } 1005 for (int I = 0; I < N; ++I) { 1006 auto V = [T = I + 10]() {}; 1007 } 1008 } 1009 } // namespace GH109083 1010