18baa5001SRichard Smith // RUN: %clang_cc1 -std=c++2a -verify %s 28baa5001SRichard Smith 38baa5001SRichard Smith template<int N> struct A {}; 48baa5001SRichard Smith 58baa5001SRichard Smith using F = bool(*)(int); 68baa5001SRichard Smith extern F *p; 78baa5001SRichard Smith extern int m; 88baa5001SRichard Smith 98baa5001SRichard Smith struct Convertible { template<typename T> operator T(); }; 108baa5001SRichard Smith f()118baa5001SRichard Smithvoid f() { 128baa5001SRichard Smith int arr1[3]; 138baa5001SRichard Smith for (int n = 5; int x : arr1) {} 148baa5001SRichard Smith 158baa5001SRichard Smith int A<0>::*arr2[3]; 168baa5001SRichard Smith for (int n = 5; int A<true ? 0 : 1>::*x : arr2) {} 178baa5001SRichard Smith 18*d29f7f1aSDanila Kutenin for (int i = 0; int x = i < 2 ? 1 : 0; i++) {} 19*d29f7f1aSDanila Kutenin 208baa5001SRichard Smith F (*arr3[3])(int); 218baa5001SRichard Smith for (int n = 5; F (*p)(int n) : arr3) {} 228baa5001SRichard Smith for (int n = 5; F (*p)(int (n)) : arr3) {} 238baa5001SRichard Smith 248baa5001SRichard Smith // Here, we have a declaration rather than an expression. 258baa5001SRichard Smith for (int n = 5; F (*p)(int (n)); ++n) {} 268baa5001SRichard Smith 278baa5001SRichard Smith // We detect whether we have a for-range-declaration before parsing so that 288baa5001SRichard Smith // we can give different diagnostics for for-range-declarations versus 298baa5001SRichard Smith // conditions (even though the rules are currently identical). 308baa5001SRichard Smith Convertible arr4[3]; 318baa5001SRichard Smith for (int n = 0; struct { operator bool(); } x = {}; ++n) {} // expected-error {{cannot be defined in a condition}} 328baa5001SRichard Smith for (int n = 0; struct { operator bool(); } x : arr4) {} // expected-error {{may not be defined in a for range declaration}} 338baa5001SRichard Smith 348baa5001SRichard Smith for (int n = 0; static int m = 0; ++n) {} // expected-error {{type name does not allow storage class}} 358baa5001SRichard Smith for (int n = 0; static int m : arr1) {} // expected-error {{loop variable 'm' may not be declared 'static'}} 36a875721dSRichard Smith 37a875721dSRichard Smith // The init-statement and range are not break / continue scopes. (But the body is.) 38a875721dSRichard Smith for (int n = ({ break; 0; }); int m : arr1) {} // expected-error {{not in loop}} 39a875721dSRichard Smith for (int n = ({ continue; 0; }); int m : arr1) {} // expected-error {{not in loop}} 40a875721dSRichard Smith for (int arr[3]; int n : *({ break; &arr; })) {} // expected-error {{not in loop}} 41a875721dSRichard Smith for (int arr[3]; int n : *({ continue; &arr; })) {} // expected-error {{not in loop}} 42a875721dSRichard Smith for (int n = 0; int m : arr1) { break; } 43a875721dSRichard Smith for (int n = 0; int m : arr1) { continue; } 448baa5001SRichard Smith } 45