1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wall -Wno-unused -verify %s 2 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s 3 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s 4 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s 5 6 template <typename return_type> 7 struct Iterator { 8 return_type operator*(); 9 Iterator operator++(); 10 bool operator!=(const Iterator); 11 }; 12 13 template <typename T> 14 struct Container { 15 typedef Iterator<T> I; 16 17 I begin(); 18 I end(); 19 }; 20 21 struct Foo {}; 22 struct Bar { 23 // Small trivially copyable types do not show a warning when copied in a 24 // range-based for loop. This size ensures the object is not considered 25 // small. 26 char s[128]; 27 Bar(Foo); 28 Bar(int); 29 operator int(); 30 }; 31 32 // Testing notes: 33 // test0 checks that the full text of the warnings and notes is correct. The 34 // rest of the tests checks a smaller portion of the text. 35 // test1-6 are set in pairs, the odd numbers are the non-reference returning 36 // versions of the even numbers. 37 // test7-9 use an array instead of a range object 38 // tests use all four versions of the loop variable, const &T, const T, T&, and 39 // T. Versions producing errors and are commented out. 40 // 41 // Conversion chart: 42 // double <=> int 43 // int <=> Bar 44 // double => Bar 45 // Foo => Bar 46 // 47 // Conversions during tests: 48 // test1-2 49 // int => int 50 // int => double 51 // int => Bar 52 // test3-4 53 // Bar => Bar 54 // Bar => int 55 // test5-6 56 // Foo => Bar 57 // test7 58 // double => double 59 // double => int 60 // double => Bar 61 // test8 62 // Foo => Foo 63 // Foo => Bar 64 // test9 65 // Bar => Bar 66 // Bar => int 67 68 void test0() { 69 Container<int> int_non_ref_container; 70 Container<int&> int_container; 71 Container<Bar&> bar_container; 72 73 for (const int &x : int_non_ref_container) {} 74 // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}} 75 // expected-note@-2 {{use non-reference type 'int'}} 76 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 77 78 for (const double &x : int_container) {} 79 // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}} 80 // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}} 81 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" 82 83 for (const Bar x : bar_container) {} 84 // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}} 85 // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}} 86 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&" 87 } 88 89 void test1() { 90 Container<int> A; 91 92 for (const int &&x : A) {} 93 // No warning, rvalue-reference to the temporary 94 for (const int &x : A) {} 95 // expected-warning@-1 {{always a copy}} 96 // expected-note@-2 {{'int'}} 97 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 98 for (const int x : A) {} 99 // No warning, non-reference type indicates copy is made 100 for (int&& x : A) {} 101 // No warning, rvalue-reference to the temporary 102 //for (int &x : A) {} 103 // Binding error 104 for (int x : A) {} 105 // No warning, non-reference type indicates copy is made 106 107 for (const double &&x : A) {} 108 // No warning, rvalue-reference to the temporary 109 for (const double &x : A) {} 110 // expected-warning@-1 {{always a copy}} 111 // expected-note@-2 {{'double'}} 112 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" 113 for (const double x : A) {} 114 // No warning, non-reference type indicates copy is made 115 for (double &&x : A) {} 116 // No warning, rvalue-reference to the temporary 117 //for (double &x : A) {} 118 // Binding error 119 for (double x : A) {} 120 // No warning, non-reference type indicates copy is made 121 122 for (const Bar &&x : A) {} 123 // No warning, rvalue-reference to the temporary 124 for (const Bar &x : A) {} 125 // expected-warning@-1 {{always a copy}} 126 // expected-note@-2 {{'Bar'}} 127 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 128 for (const Bar x : A) {} 129 // No warning, non-reference type indicates copy is made 130 for (Bar &&x : A) {} 131 // No warning, rvalue-reference to the temporary 132 //for (Bar &x : A) {} 133 // Binding error 134 for (Bar x : A) {} 135 // No warning, non-reference type indicates copy is made 136 } 137 138 void test2() { 139 Container<int&> B; 140 141 //for (const int &&x : B) {} 142 // Binding error 143 for (const int &x : B) {} 144 // No warning, this reference is not a temporary 145 for (const int x : B) {} 146 // No warning on POD copy 147 //for (int &x : B) {} 148 // Binding error 149 for (int &x : B) {} 150 // No warning 151 for (int x : B) {} 152 // No warning 153 154 for (const double &&x : B) {} 155 // expected-warning@-1 {{resulting in a copy}} 156 // expected-note-re@-2 {{'double'{{.*}}'const int &'}} 157 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:23}:"" 158 for (const double &x : B) {} 159 // expected-warning@-1 {{resulting in a copy}} 160 // expected-note-re@-2 {{'double'{{.*}}'const int &'}} 161 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" 162 for (const double x : B) {} 163 for (double &&x : B) {} 164 // expected-warning@-1 {{resulting in a copy}} 165 // expected-note-re@-2 {{'double'{{.*}}'const int &'}} 166 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:17}:"" 167 //for (double &x : B) {} 168 // Binding error 169 for (double x : B) {} 170 // No warning 171 172 for (const Bar &&x : B) {} 173 // expected-warning@-1 {{resulting in a copy}} 174 // expected-note@-2 {{'Bar'}} 175 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 176 for (const Bar &x : B) {} 177 // expected-warning@-1 {{resulting in a copy}} 178 // expected-note@-2 {{'Bar'}} 179 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 180 for (const Bar x : B) {} 181 for (Bar &&x : B) {} 182 // expected-warning@-1 {{resulting in a copy}} 183 // expected-note@-2 {{'Bar'}} 184 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 185 //for (Bar &x : B) {} 186 // Binding error 187 for (Bar x : B) {} 188 // No warning 189 } 190 191 void test3() { 192 Container<Bar> C; 193 194 for (const Bar &&x : C) {} 195 // No warning, rvalue-reference to the temporary 196 for (const Bar &x : C) {} 197 // expected-warning@-1 {{always a copy}} 198 // expected-note@-2 {{'Bar'}} 199 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 200 for (const Bar x : C) {} 201 // No warning, non-reference type indicates copy is made 202 for (Bar &&x : C) {} 203 // No warning, rvalue-reference to the temporary 204 //for (Bar &x : C) {} 205 // Binding error 206 for (Bar x : C) {} 207 // No warning, non-reference type indicates copy is made 208 209 for (const int &&x : C) {} 210 // No warning, rvalue-reference to the temporary 211 for (const int &x : C) {} 212 // expected-warning@-1 {{always a copy}} 213 // expected-note@-2 {{'int'}} 214 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 215 for (const int x : C) {} 216 // No warning, copy made 217 for (int &&x : C) {} 218 // No warning, rvalue-reference to the temporary 219 //for (int &x : C) {} 220 // Binding error 221 for (int x : C) {} 222 // No warning, copy made 223 } 224 225 void test4() { 226 Container<Bar&> D; 227 228 //for (const Bar &&x : D) {} 229 // Binding error 230 for (const Bar &x : D) {} 231 // No warning, this reference is not a temporary 232 for (const Bar x : D) {} 233 // expected-warning@-1 {{creates a copy}} 234 // expected-note@-2 {{'const Bar &'}} 235 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&" 236 //for (Bar &&x : D) {} 237 // Binding error 238 for (Bar &x : D) {} 239 // No warning 240 for (Bar x : D) {} 241 // No warning 242 243 for (const int &&x : D) {} 244 // expected-warning@-1 {{resulting in a copy}} 245 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 246 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 247 for (const int &x : D) {} 248 // expected-warning@-1 {{resulting in a copy}} 249 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 250 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 251 for (const int x : D) {} 252 // No warning 253 for (int &&x : D) {} 254 // expected-warning@-1 {{resulting in a copy}} 255 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 256 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 257 //for (int &x : D) {} 258 // Binding error 259 for (int x : D) {} 260 // No warning 261 } 262 263 void test5() { 264 Container<Foo> E; 265 266 for (const Bar &&x : E) {} 267 // No warning, rvalue-reference to the temporary 268 for (const Bar &x : E) {} 269 // expected-warning@-1 {{always a copy}} 270 // expected-note@-2 {{'Bar'}} 271 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 272 for (const Bar x : E) {} 273 // No warning, non-reference type indicates copy is made 274 for (Bar &&x : E) {} 275 // No warning, rvalue-reference to the temporary 276 //for (Bar &x : E) {} 277 // Binding error 278 for (Bar x : E) {} 279 // No warning, non-reference type indicates copy is made 280 } 281 282 void test6() { 283 Container<Foo&> F; 284 285 for (const Bar &&x : F) {} 286 // expected-warning@-1 {{resulting in a copy}} 287 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 288 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 289 for (const Bar &x : F) {} 290 // expected-warning@-1 {{resulting in a copy}} 291 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 292 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 293 for (const Bar x : F) {} 294 // No warning. 295 for (Bar &&x : F) {} 296 // expected-warning@-1 {{resulting in a copy}} 297 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 298 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 299 //for (Bar &x : F) {} 300 // Binding error 301 for (Bar x : F) {} 302 // No warning 303 } 304 305 void test7() { 306 double G[2]; 307 308 //for (const double &&x : G) {} 309 // Binding error 310 for (const double &x : G) {} 311 // No warning 312 for (const double x : G) {} 313 // No warning on POD copy 314 //for (double &&x : G) {} 315 // Binding error 316 for (double &x : G) {} 317 // No warning 318 for (double x : G) {} 319 // No warning 320 321 for (const int &&x : G) {} 322 // expected-warning@-1 {{resulting in a copy}} 323 // expected-note-re@-2 {{'int'{{.*}}'const double &'}} 324 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 325 for (const int &x : G) {} 326 // expected-warning@-1 {{resulting in a copy}} 327 // expected-note-re@-2 {{'int'{{.*}}'const double &'}} 328 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 329 for (const int x : G) {} 330 // No warning 331 for (int &&x : G) {} 332 // expected-warning@-1 {{resulting in a copy}} 333 // expected-note-re@-2 {{'int'{{.*}}'const double &'}} 334 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 335 //for (int &x : G) {} 336 // Binding error 337 for (int x : G) {} 338 // No warning 339 340 for (const Bar &&x : G) {} 341 // expected-warning@-1 {{resulting in a copy}} 342 // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} 343 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 344 for (const Bar &x : G) {} 345 // expected-warning@-1 {{resulting in a copy}} 346 // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} 347 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 348 for (const Bar x : G) {} 349 // No warning 350 for (Bar &&x : G) {} 351 // expected-warning@-1 {{resulting in a copy}} 352 // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} 353 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 354 //for (Bar &x : G) {} 355 // Binding error 356 for (Bar x : G) {} 357 // No warning 358 } 359 360 void test8() { 361 Foo H[2]; 362 363 //for (const Foo &&x : H) {} 364 // Binding error 365 for (const Foo &x : H) {} 366 // No warning 367 for (const Foo x : H) {} 368 // No warning on POD copy 369 //for (Foo &&x : H) {} 370 // Binding error 371 for (Foo &x : H) {} 372 // No warning 373 for (Foo x : H) {} 374 // No warning 375 376 for (const Bar &&x : H) {} 377 // expected-warning@-1 {{resulting in a copy}} 378 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 379 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 380 for (const Bar &x : H) {} 381 // expected-warning@-1 {{resulting in a copy}} 382 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 383 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 384 for (const Bar x : H) {} 385 // No warning 386 for (Bar &&x: H) {} 387 // expected-warning@-1 {{resulting in a copy}} 388 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 389 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 390 //for (Bar &x: H) {} 391 // Binding error 392 for (Bar x: H) {} 393 // No warning 394 } 395 396 void test9() { 397 Bar I[2] = {1,2}; 398 399 //for (const Bar &&x : I) {} 400 // Binding error 401 for (const Bar &x : I) {} 402 // No warning 403 for (const Bar x : I) {} 404 // expected-warning@-1 {{creates a copy}} 405 // expected-note@-2 {{'const Bar &'}} 406 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&" 407 //for (Bar &&x : I) {} 408 // Binding error 409 for (Bar &x : I) {} 410 // No warning 411 for (Bar x : I) {} 412 // No warning 413 414 for (const int &&x : I) {} 415 // expected-warning@-1 {{resulting in a copy}} 416 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 417 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 418 for (const int &x : I) {} 419 // expected-warning@-1 {{resulting in a copy}} 420 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 421 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 422 for (const int x : I) {} 423 // No warning 424 for (int &&x : I) {} 425 // expected-warning@-1 {{resulting in a copy}} 426 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 427 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" 428 //for (int &x : I) {} 429 // Binding error 430 for (int x : I) {} 431 // No warning 432 } 433 434 void test10() { 435 Container<Bar> C; 436 437 for (const Bar &x : C) {} 438 // expected-warning@-1 {{always a copy}} 439 // expected-note@-2 {{'Bar'}} 440 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 441 442 for (const Bar& x : C) {} 443 // expected-warning@-1 {{always a copy}} 444 // expected-note@-2 {{'Bar'}} 445 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"" 446 447 for (const Bar & x : C) {} 448 // expected-warning@-1 {{always a copy}} 449 // expected-note@-2 {{'Bar'}} 450 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" 451 452 for (const Bar&x : C) {} 453 // expected-warning@-1 {{always a copy}} 454 // expected-note@-2 {{'Bar'}} 455 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" " 456 } 457 458 template <class T> 459 void test_template_function() { 460 // In a template instantiation the diagnostics should not be emitted for 461 // loops with dependent types. 462 Container<Bar> C; 463 for (const Bar &x : C) {} 464 // expected-warning@-1 {{always a copy}} 465 // expected-note@-2 {{'Bar'}} 466 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" 467 468 Container<T> Dependent; 469 for (const T &x : Dependent) {} 470 } 471 template void test_template_function<Bar>(); 472 473 template <class T> 474 struct test_template_struct { 475 static void static_member() { 476 Container<Bar> C; 477 for (const Bar &x : C) {} 478 // expected-warning@-1 {{always a copy}} 479 // expected-note@-2 {{'Bar'}} 480 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" 481 482 Container<T> Dependent; 483 for (const T &x : Dependent) {} 484 } 485 486 void member() { 487 Container<Bar> C; 488 for (const Bar &x : C) {} 489 // expected-warning@-1 {{always a copy}} 490 // expected-note@-2 {{'Bar'}} 491 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" 492 493 Container<T> Dependent; 494 for (const T &x : Dependent) {} 495 } 496 }; 497 template struct test_template_struct<Bar>; 498 499 struct test_struct_with_templated_member { 500 void member() { 501 Container<Bar> C; 502 for (const Bar &x : C) {} 503 // expected-warning@-1 {{always a copy}} 504 // expected-note@-2 {{'Bar'}} 505 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" 506 } 507 508 template <class T> 509 void template_member() { 510 Container<Bar> C; 511 for (const Bar &x : C) {} 512 // expected-warning@-1 {{always a copy}} 513 // expected-note@-2 {{'Bar'}} 514 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" 515 516 Container<T> Dependent; 517 for (const T &x : Dependent) {} 518 } 519 }; 520 template void test_struct_with_templated_member::template_member<Bar>(); 521 522 #define TEST_MACRO \ 523 void test_macro() { \ 524 Container<Bar> C; \ 525 for (const Bar &x : C) {} \ 526 } 527 528 TEST_MACRO 529