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 | } |
35 | |