|
1 | | -// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -fdeclspec -fblocks -verify |
| 1 | +// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -fdeclspec -fblocks -Wno-vla-cxx-extension -verify |
2 | 2 | namespace std { |
3 | 3 | template <typename T> |
4 | 4 | struct initializer_list { |
@@ -470,7 +470,7 @@ void overload_set(int); // expected-note 2 {{possible target for call}} |
470 | 470 | void overload_set(long); // expected-note 2 {{possible target for call}} |
471 | 471 |
|
472 | 472 | void invalid_types() { |
473 | | - template for (auto x : void()) {} // expected-error {{cannot expand expression of type 'void'}} |
| 473 | + template for (auto x : void()) {} // expected-error {{cannot expand expression of incomplete type 'void'}} |
474 | 474 | template for (auto x : 1) {} // expected-error {{cannot expand expression of type 'int'}} |
475 | 475 | template for (auto x : 1.f) {} // expected-error {{cannot expand expression of type 'float'}} |
476 | 476 | template for (auto x : 'c') {} // expected-error {{cannot expand expression of type 'char'}} |
@@ -1040,3 +1040,43 @@ void init_list_bad() { |
1040 | 1040 | template for (auto y : {{1}, {2}, {3, {4}}, {{{5}}}}); // expected-error {{cannot deduce actual type for variable 'y' with type 'auto' from initializer list}} \ |
1041 | 1041 | expected-note {{in instantiation of expansion statement requested here}} |
1042 | 1042 | } |
| 1043 | + |
| 1044 | +// Test that the init statement is evaluated even if the expansion statement |
| 1045 | +// expands to nothing. |
| 1046 | +constexpr int init_stmt_empty_expansion() { |
| 1047 | + static constexpr String empty{""}; |
| 1048 | + int x = 0; |
| 1049 | + template for (int _ = x += 1; auto i : {}) {} |
| 1050 | + template for (int _ = x += 2; auto i : empty) {} |
| 1051 | + template for (int _ = x += 3; auto i : Empty()) {} |
| 1052 | + return x; |
| 1053 | +} |
| 1054 | + |
| 1055 | +static_assert(init_stmt_empty_expansion() == 6); |
| 1056 | + |
| 1057 | +void vla(int n) { |
| 1058 | + int a[n]; |
| 1059 | + template for (int x : a) {} // expected-error {{cannot expand variable length array type 'int[n]'}} |
| 1060 | +} |
| 1061 | + |
| 1062 | +template <typename T> |
| 1063 | +void template_vla(T& a) { // expected-note {{variably modified type 'int[n]' cannot be used as a template argument}} |
| 1064 | + template for (int x : a) {} |
| 1065 | +} |
| 1066 | + |
| 1067 | +void instantiate_template_vla(int n) { |
| 1068 | + int a[n]; |
| 1069 | + template_vla(a); // expected-error {{no matching function for call to 'template_vla'}} |
| 1070 | +} |
| 1071 | + |
| 1072 | +struct Incomplete; // expected-note 2 {{forward declaration of 'Incomplete'}} |
| 1073 | +void incomplete_type(Incomplete& s) { |
| 1074 | + template for (int x : s) {} // expected-error {{cannot expand expression of incomplete type 'Incomplete'}} |
| 1075 | +} |
| 1076 | + |
| 1077 | +template <typename T> |
| 1078 | +void dependent_incomplete_type(T& s) { |
| 1079 | + template for (int x : s) {} // expected-error {{cannot expand expression of incomplete type 'Incomplete'}} |
| 1080 | +} |
| 1081 | + |
| 1082 | +template void dependent_incomplete_type<Incomplete>(Incomplete&); // expected-note {{in instantiation of function template specialization 'dependent_incomplete_type<Incomplete>' requested here}} |
0 commit comments