@@ -982,6 +982,24 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
}
}
+static bool
+cp_lexer_next_token_is_c_type_qual (cp_lexer *lexer)
+{
+ if (cp_lexer_next_token_is_keyword (lexer, RID_CONST)
+ || cp_lexer_next_token_is_keyword (lexer, RID_VOLATILE))
+ return true;
+
+ cp_token *token = cp_lexer_peek_token (lexer);
+ if (token->type == CPP_NAME)
+ {
+ tree name = token->u.value;
+ const char *p = IDENTIFIER_POINTER (name);
+ return !strcmp (p, "restrict") || !strcmp (p, "_Atomic");
+ }
+
+ return false;
+}
+
/* Returns TRUE iff the token T begins a decltype type. */
static bool
@@ -18998,10 +19016,40 @@ cp_parser_direct_declarator (cp_parser* parser,
cp_lexer_consume_token (parser->lexer);
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
+
+ /* If static or type-qualifier or * immediately follows [,
+ report error. */
+ if (current_binding_level->kind == sk_function_parms)
+ {
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
+ {
+ error_at (token->location,
+ "static array size is a C99 feature, "
+ "not permitted in C++");
+ bounds = error_mark_node;
+ }
+ else if (cp_lexer_next_token_is_c_type_qual (parser->lexer))
+ {
+ error_at (token->location,
+ "qualifier in array size is a C99 feature, "
+ "not permitted in C++");
+ bounds = error_mark_node;
+ }
+
+ else if (token->type == CPP_MULT)
+ {
+ error_at (token->location,
+ "variable-length array size is a C99 feature, "
+ "not permitted in C++");
+ bounds = error_mark_node;
+ }
+ }
+
/* If the next token is `]', then there is no
constant-expression. */
- if (token->type != CPP_CLOSE_SQUARE)
+ if (token->type != CPP_CLOSE_SQUARE && bounds != error_mark_node)
{
+
bool non_constant_p;
bounds
= cp_parser_constant_expression (parser,
new file mode 100644
@@ -0,0 +1,33 @@
+// { dg-do compile }
+
+void f1(int a[static 10]); /* { dg-error "static array size is a C99 feature" } */
+/* { dg-error "expected '\\]' before 'static'" "" { target *-*-* } 3 } */
+/* { dg-error "expected '\\)' before 'static'" "" { target *-*-* } 3 } */
+/* { dg-error "expected initializer before 'static'" "" { target *-*-* } 3 } */
+
+void f2(int a[const 10]); /* { dg-error "qualifier in array size is a C99 feature" } */
+/* { dg-error "expected '\\]' before 'const'" "" { target *-*-* } 8 } */
+/* { dg-error "expected '\\)' before 'const'" "" { target *-*-* } 8 } */
+/* { dg-error "expected initializer before numeric constant" "" { target *-*-* } 8 } */
+
+void f3(int a[restrict 10]); /* { dg-error "qualifier in array size is a C99 feature" } */
+/* { dg-error "expected '\\]' before 'restrict'" "" { target *-*-* } 13 } */
+/* { dg-error "expected '\\)' before 'restrict'" "" { target *-*-* } 13 } */
+/* { dg-error "expected initializer before 'restrict'" "" { target *-*-* } 13 } */
+
+void f4(int a[volatile 10]); /* { dg-error "qualifier in array size is a C99 feature" } */
+/* { dg-error "expected '\\]' before 'volatile'" "" { target *-*-* } 18 } */
+/* { dg-error "expected '\\)' before 'volatile'" "" { target *-*-* } 18 } */
+/* { dg-error "expected initializer before numeric constant" "" { target *-*-* } 18 } */
+
+
+void f4(int a[_Atomic 10]); /* { dg-error "qualifier in array size is a C99 feature" } */
+/* { dg-error "expected '\\]' before '_Atomic'" "" { target *-*-* } 24 } */
+/* { dg-error "expected '\\)' before '_Atomic'" "" { target *-*-* } 24 } */
+/* { dg-error "expected initializer before '_Atomic'" "" { target *-*-* } 24 } */
+
+
+void f5(int a[*]); /* { dg-error "variable-length array size is a C99 feature" } */
+/* { dg-error "expected ']' before '*' token" "" { target *-*-* } 24 } */
+/* { dg-error "expected '\\)' before '*' token" "" { target *-*-* } 24 } */
+/* { dg-error "expected initializer before '*' token" "" { target *-*-* } 24 } */