brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.6 KiB · 7fd7fcd Raw
529 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wall -Wrange-loop-bind-reference -Wno-unused -verify %s2// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s3// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s4// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s5 6template <typename return_type>7struct Iterator {8  return_type operator*();9  Iterator operator++();10  bool operator!=(const Iterator);11};12 13template <typename T>14struct Container {15  typedef Iterator<T> I;16 17  I begin();18  I end();19};20 21struct Foo {};22struct Bar {23  // Small trivially copyable types do not show a warning when copied in a24  // range-based for loop. This size ensures the object is not considered25  // 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.  The34//   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 returning36//   versions of the even numbers.37// test7-9 use an array instead of a range object38// tests use all four versions of the loop variable, const &T, const T, T&, and39//   T.  Versions producing errors and are commented out.40//41// Conversion chart:42//   double <=> int43//   int    <=> Bar44//   double  => Bar45//   Foo     => Bar46//47// Conversions during tests:48// test1-249//   int => int50//   int => double51//   int => Bar52// test3-453//   Bar => Bar54//   Bar => int55// test5-656//   Foo => Bar57// test758//   double => double59//   double => int60//   double => Bar61// test862//   Foo => Foo63//   Foo => Bar64// test965//   Bar => Bar66//   Bar => int67 68void 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' binds to a temporary value produced by a range of type 'Container<int>'}}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' of type 'const double &' binds to a temporary constructed from type 'int &'}}80  // expected-note@-2 {{use non-reference type 'double' to make construction explicit 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' 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 89void test1() {90  Container<int> A;91 92  for (const int &&x : A) {}93  // No warning, rvalue-reference to the temporary94  for (const int &x : A) {}95  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made100  for (int&& x : A) {}101  // No warning, rvalue-reference to the temporary102  //for (int &x : A) {}103  // Binding error104  for (int x : A) {}105  // No warning, non-reference type indicates copy is made106 107  for (const double &&x : A) {}108  // No warning, rvalue-reference to the temporary109  for (const double &x : A) {}110  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made115  for (double &&x : A) {}116  // No warning, rvalue-reference to the temporary117  //for (double &x : A) {}118  // Binding error119  for (double x : A) {}120  // No warning, non-reference type indicates copy is made121 122  for (const Bar &&x : A) {}123  // No warning, rvalue-reference to the temporary124  for (const Bar &x : A) {}125  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made130  for (Bar &&x : A) {}131  // No warning, rvalue-reference to the temporary132  //for (Bar &x : A) {}133  // Binding error134  for (Bar x : A) {}135  // No warning, non-reference type indicates copy is made136}137 138void test2() {139  Container<int&> B;140 141  //for (const int &&x : B) {}142  // Binding error143  for (const int &x : B) {}144  // No warning, this reference is not a temporary145  for (const int x : B) {}146  // No warning on POD copy147  //for (int &x : B) {}148  // Binding error149  for (int &x : B) {}150  // No warning151  for (int x : B) {}152  // No warning153 154  for (const double &&x : B) {}155  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 error169  for (double x : B) {}170  // No warning171 172  for (const Bar &&x : B) {}173  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}183  // expected-note@-2 {{'Bar'}}184  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:""185  //for (Bar &x : B) {}186  // Binding error187  for (Bar x : B) {}188  // No warning189}190 191void test3() {192  Container<Bar> C;193 194  for (const Bar &&x : C) {}195  // No warning, rvalue-reference to the temporary196  for (const Bar &x : C) {}197  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made202  for (Bar &&x : C) {}203  // No warning, rvalue-reference to the temporary204  //for (Bar &x : C) {}205  // Binding error206  for (Bar x : C) {}207  // No warning, non-reference type indicates copy is made208 209  for (const int &&x : C) {}210  // No warning, rvalue-reference to the temporary211  for (const int &x : C) {}212  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made217  for (int &&x : C) {}218  // No warning, rvalue-reference to the temporary219  //for (int &x : C) {}220  // Binding error221  for (int x : C) {}222  // No warning, copy made223}224 225void test4() {226  Container<Bar&> D;227 228  //for (const Bar &&x : D) {}229  // Binding error230  for (const Bar &x : D) {}231  // No warning, this reference is not a temporary232  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 error238  for (Bar &x : D) {}239  // No warning240  for (Bar x : D) {}241  // No warning242 243  for (const int &&x : D) {}244  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 warning253  for (int &&x : D) {}254  // expected-warning@-1 {{binds to a temporary constructed from}}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 error259  for (int x : D) {}260  // No warning261}262 263void test5() {264  Container<Foo> E;265 266  for (const Bar &&x : E) {}267  // No warning, rvalue-reference to the temporary268  for (const Bar &x : E) {}269  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 made274  for (Bar &&x : E) {}275  // No warning, rvalue-reference to the temporary276  //for (Bar &x : E) {}277  // Binding error278  for (Bar x : E) {}279  // No warning, non-reference type indicates copy is made280}281 282void test6() {283  Container<Foo&> F;284 285  for (const Bar &&x : F) {}286  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 error301  for (Bar x : F) {}302  // No warning303}304 305void test7() {306  double G[2];307 308  //for (const double &&x : G) {}309  // Binding error310  for (const double &x : G) {}311  // No warning312  for (const double x : G) {}313  // No warning on POD copy314  //for (double &&x : G) {}315  // Binding error316  for (double &x : G) {}317  // No warning318  for (double x : G) {}319  // No warning320 321  for (const int &&x : G) {}322  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 warning331  for (int &&x : G) {}332  // expected-warning@-1 {{binds to a temporary constructed from}}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 error337  for (int x : G) {}338  // No warning339 340  for (const Bar &&x : G) {}341  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 warning350  for (Bar &&x : G) {}351  // expected-warning@-1 {{binds to a temporary constructed from}}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 error356  for (Bar x : G) {}357  // No warning358}359 360void test8() {361  Foo H[2];362 363  //for (const Foo &&x : H) {}364  // Binding error365  for (const Foo &x : H) {}366  // No warning367  for (const Foo x : H) {}368  // No warning on POD copy369  //for (Foo &&x : H) {}370  // Binding error371  for (Foo &x : H) {}372  // No warning373  for (Foo x : H) {}374  // No warning375 376  for (const Bar &&x : H) {}377  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 warning386  for (Bar &&x: H) {}387  // expected-warning@-1 {{binds to a temporary constructed from}}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 error392  for (Bar x: H) {}393  // No warning394}395 396void test9() {397  Bar I[2] = {1,2};398 399  //for (const Bar &&x : I) {}400  // Binding error401  for (const Bar &x : I) {}402  // No warning403  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 error409  for (Bar &x : I) {}410  // No warning411  for (Bar x : I) {}412  // No warning413 414  for (const int &&x : I) {}415  // expected-warning@-1 {{binds to a temporary constructed from}}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 {{binds to a temporary constructed from}}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 warning424  for (int &&x : I) {}425  // expected-warning@-1 {{binds to a temporary constructed from}}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 error430  for (int x : I) {}431  // No warning432}433 434void test10() {435  Container<Bar> C;436 437  for (const Bar &x : C) {}438  // expected-warning@-1 {{binds to a temporary value produced by a range}}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 {{binds to a temporary value produced by a range}}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 {{binds to a temporary value produced by a range}}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 {{binds to a temporary value produced by a range}}454  // expected-note@-2 {{'Bar'}}455  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" "456}457 458template <class T>459void test_template_function() {460  // In a template instantiation the diagnostics should not be emitted for461  // loops with dependent types.462  Container<Bar> C;463  for (const Bar &x : C) {}464  // expected-warning@-1 {{binds to a temporary value produced by a range}}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}471template void test_template_function<Bar>();472 473template <class T>474struct test_template_struct {475  static void static_member() {476    Container<Bar> C;477    for (const Bar &x : C) {}478    // expected-warning@-1 {{binds to a temporary value produced by a range}}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 {{binds to a temporary value produced by a range}}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};497template struct test_template_struct<Bar>;498 499struct test_struct_with_templated_member {500  void member() {501    Container<Bar> C;502    for (const Bar &x : C) {}503    // expected-warning@-1 {{binds to a temporary value produced by a range}}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 {{binds to a temporary value produced by a range}}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};520template 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 528TEST_MACRO529