1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wloop-analysis -verify %s 2// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wrange-loop-analysis -verify %s 3 4template <typename return_type> 5struct Iterator { 6 return_type operator*(); 7 Iterator operator++(); 8 bool operator!=(const Iterator); 9}; 10 11template <typename T> 12struct Container { 13 typedef Iterator<T> I; 14 15 I begin(); 16 I end(); 17}; 18 19struct Foo {}; 20struct Bar { 21 Bar(Foo); 22 Bar(int); 23 operator int(); 24}; 25 26// Testing notes: 27// test0 checks that the full text of the warnings and notes is correct. The 28// rest of the tests checks a smaller portion of the text. 29// test1-6 are set in pairs, the odd numbers are the non-reference returning 30// versions of the even numbers. 31// test7-9 use an array instead of a range object 32// tests use all four versions of the loop varaible, const &T, const T, T&, and 33// T. Versions producing errors and are commented out. 34// 35// Conversion chart: 36// double <=> int 37// int <=> Bar 38// double => Bar 39// Foo => Bar 40// 41// Conversions during tests: 42// test1-2 43// int => int 44// int => double 45// int => Bar 46// test3-4 47// Bar => Bar 48// Bar => int 49// test5-6 50// Foo => Bar 51// test7 52// double => double 53// double => int 54// double => Bar 55// test8 56// Foo => Foo 57// Foo => Bar 58// test9 59// Bar => Bar 60// Bar => int 61 62void test0() { 63 Container<int> int_non_ref_container; 64 Container<int&> int_container; 65 Container<Bar&> bar_container; 66 67 for (const int &x : int_non_ref_container) {} 68 // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}} 69 // expected-note@-2 {{use non-reference type 'int'}} 70 71 for (const double &x : int_container) {} 72 // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}} 73 // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}} 74 75 for (const Bar x : bar_container) {} 76 // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}} 77 // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}} 78} 79 80void test1() { 81 Container<int> A; 82 83 for (const int &x : A) {} 84 // expected-warning@-1 {{always a copy}} 85 // expected-note@-2 {{'int'}} 86 for (const int x : A) {} 87 // No warning, non-reference type indicates copy is made 88 //for (int &x : A) {} 89 // Binding error 90 for (int x : A) {} 91 // No warning, non-reference type indicates copy is made 92 93 for (const double &x : A) {} 94 // expected-warning@-1 {{always a copy}} 95 // expected-note@-2 {{'double'}} 96 for (const double x : A) {} 97 // No warning, non-reference type indicates copy is made 98 //for (double &x : A) {} 99 // Binding error 100 for (double x : A) {} 101 // No warning, non-reference type indicates copy is made 102 103 for (const Bar &x : A) {} 104 // expected-warning@-1 {{always a copy}} 105 // expected-note@-2 {{'Bar'}} 106 for (const Bar x : A) {} 107 // No warning, non-reference type indicates copy is made 108 //for (Bar &x : A) {} 109 // Binding error 110 for (Bar x : A) {} 111 // No warning, non-reference type indicates copy is made 112} 113 114void test2() { 115 Container<int&> B; 116 117 for (const int &x : B) {} 118 // No warning, this reference is not a temporary 119 for (const int x : B) {} 120 // No warning on POD copy 121 for (int &x : B) {} 122 // No warning 123 for (int x : B) {} 124 // No warning 125 126 for (const double &x : B) {} 127 // expected-warning@-1 {{resulting in a copy}} 128 // expected-note-re@-2 {{'double'{{.*}}'const int &'}} 129 for (const double x : B) {} 130 //for (double &x : B) {} 131 // Binding error 132 for (double x : B) {} 133 // No warning 134 135 for (const Bar &x : B) {} 136 // expected-warning@-1 {{resulting in a copy}} 137 // expected-note@-2 {{'Bar'}} 138 for (const Bar x : B) {} 139 //for (Bar &x : B) {} 140 // Binding error 141 for (Bar x : B) {} 142 // No warning 143} 144 145void test3() { 146 Container<Bar> C; 147 148 for (const Bar &x : C) {} 149 // expected-warning@-1 {{always a copy}} 150 // expected-note@-2 {{'Bar'}} 151 for (const Bar x : C) {} 152 // No warning, non-reference type indicates copy is made 153 //for (Bar &x : C) {} 154 // Binding error 155 for (Bar x : C) {} 156 // No warning, non-reference type indicates copy is made 157 158 for (const int &x : C) {} 159 // expected-warning@-1 {{always a copy}} 160 // expected-note@-2 {{'int'}} 161 for (const int x : C) {} 162 // No warning, copy made 163 //for (int &x : C) {} 164 // Binding error 165 for (int x : C) {} 166 // No warning, copy made 167} 168 169void test4() { 170 Container<Bar&> D; 171 172 for (const Bar &x : D) {} 173 // No warning, this reference is not a temporary 174 for (const Bar x : D) {} 175 // expected-warning@-1 {{creates a copy}} 176 // expected-note@-2 {{'const Bar &'}} 177 for (Bar &x : D) {} 178 // No warning 179 for (Bar x : D) {} 180 // No warning 181 182 for (const int &x : D) {} 183 // expected-warning@-1 {{resulting in a copy}} 184 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 185 for (const int x : D) {} 186 // No warning 187 //for (int &x : D) {} 188 // Binding error 189 for (int x : D) {} 190 // No warning 191} 192 193void test5() { 194 Container<Foo> E; 195 196 for (const Bar &x : E) {} 197 // expected-warning@-1 {{always a copy}} 198 // expected-note@-2 {{'Bar'}} 199 for (const Bar x : E) {} 200 // No warning, non-reference type indicates copy is made 201 //for (Bar &x : E) {} 202 // Binding error 203 for (Bar x : E) {} 204 // No warning, non-reference type indicates copy is made 205} 206 207void test6() { 208 Container<Foo&> F; 209 210 for (const Bar &x : F) {} 211 // expected-warning@-1 {{resulting in a copy}} 212 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 213 for (const Bar x : F) {} 214 // No warning. 215 //for (Bar &x : F) {} 216 // Binding error 217 for (Bar x : F) {} 218 // No warning 219} 220 221void test7() { 222 double G[2]; 223 224 for (const double &x : G) {} 225 // No warning 226 for (const double x : G) {} 227 // No warning on POD copy 228 for (double &x : G) {} 229 // No warning 230 for (double x : G) {} 231 // No warning 232 233 for (const int &x : G) {} 234 // expected-warning@-1 {{resulting in a copy}} 235 // expected-note-re@-2 {{'int'{{.*}}'const double &'}} 236 for (const int x : G) {} 237 // No warning 238 //for (int &x : G) {} 239 // Binding error 240 for (int x : G) {} 241 // No warning 242 243 for (const Bar &x : G) {} 244 // expected-warning@-1 {{resulting in a copy}} 245 // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} 246 for (const Bar x : G) {} 247 // No warning 248 //for (int &Bar : G) {} 249 // Binding error 250 for (int Bar : G) {} 251 // No warning 252} 253 254void test8() { 255 Foo H[2]; 256 257 for (const Foo &x : H) {} 258 // No warning 259 for (const Foo x : H) {} 260 // No warning on POD copy 261 for (Foo &x : H) {} 262 // No warning 263 for (Foo x : H) {} 264 // No warning 265 266 for (const Bar &x : H) {} 267 // expected-warning@-1 {{resulting in a copy}} 268 // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} 269 for (const Bar x : H) {} 270 // No warning 271 //for (Bar &x: H) {} 272 // Binding error 273 for (Bar x: H) {} 274 // No warning 275} 276 277void test9() { 278 Bar I[2] = {1,2}; 279 280 for (const Bar &x : I) {} 281 // No warning 282 for (const Bar x : I) {} 283 // expected-warning@-1 {{creates a copy}} 284 // expected-note@-2 {{'const Bar &'}} 285 for (Bar &x : I) {} 286 // No warning 287 for (Bar x : I) {} 288 // No warning 289 290 for (const int &x : I) {} 291 // expected-warning@-1 {{resulting in a copy}} 292 // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} 293 for (const int x : I) {} 294 // No warning 295 //for (int &x : I) {} 296 // Binding error 297 for (int x : I) {} 298 // No warning 299} 300