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