Richard Smith | 8baa500 | 2018-09-28 18:44:09 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++2a -verify %s |
| 2 | |
| 3 | template<int N> struct A {}; |
| 4 | |
| 5 | using F = bool(*)(int); |
| 6 | extern F *p; |
| 7 | extern int m; |
| 8 | |
| 9 | struct Convertible { template<typename T> operator T(); }; |
| 10 | |
| 11 | void f() { |
| 12 | int arr1[3]; |
| 13 | for (int n = 5; int x : arr1) {} |
| 14 | |
| 15 | int A<0>::*arr2[3]; |
| 16 | for (int n = 5; int A<true ? 0 : 1>::*x : arr2) {} |
| 17 | |
| 18 | F (*arr3[3])(int); |
| 19 | for (int n = 5; F (*p)(int n) : arr3) {} |
| 20 | for (int n = 5; F (*p)(int (n)) : arr3) {} |
| 21 | |
| 22 | // Here, we have a declaration rather than an expression. |
| 23 | for (int n = 5; F (*p)(int (n)); ++n) {} |
| 24 | |
| 25 | // We detect whether we have a for-range-declaration before parsing so that |
| 26 | // we can give different diagnostics for for-range-declarations versus |
| 27 | // conditions (even though the rules are currently identical). |
| 28 | Convertible arr4[3]; |
| 29 | for (int n = 0; struct { operator bool(); } x = {}; ++n) {} // expected-error {{cannot be defined in a condition}} |
| 30 | for (int n = 0; struct { operator bool(); } x : arr4) {} // expected-error {{may not be defined in a for range declaration}} |
| 31 | |
| 32 | for (int n = 0; static int m = 0; ++n) {} // expected-error {{type name does not allow storage class}} |
| 33 | for (int n = 0; static int m : arr1) {} // expected-error {{loop variable 'm' may not be declared 'static'}} |
| 34 | } |