Hi,
the issue is that we accept a stray comma at the end of a member
declaration. The reason is very simple: toward the end of the
cp_parser_member_declaration main loop, we simply consume a comma token,
without checking that isn't immediately followed by a semi colon. Thus
the below, which passes testing on x86_64-linux. Alternately something
like patch *_2?
Thanks,
Paolo.
//////////////////////
/cp
2012-11-19 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/55368
* parser.c (cp_parser_member_declaration): Emit an error in case
of stray comma at end of member declaration.
/testsuite
2012-11-19 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/55368
* g++.dg/parse/struct-5.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 193618)
+++ cp/parser.c (working copy)
@@ -19407,7 +19406,15 @@ cp_parser_member_declaration (cp_parser* parser)
parser->object_scope = NULL_TREE;
/* If it's a `,', then there are more declarators. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
- cp_lexer_consume_token (parser->lexer);
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_token *token = cp_lexer_previous_token (parser->lexer);
+ error_at (token->location,
+ "stray %<,%> at end of member declaration");
+ }
+ }
/* If the next token isn't a `;', then we have a parse error. */
else if (cp_lexer_next_token_is_not (parser->lexer,
CPP_SEMICOLON))
Index: testsuite/g++.dg/parse/struct-5.C
===================================================================
--- testsuite/g++.dg/parse/struct-5.C (revision 0)
+++ testsuite/g++.dg/parse/struct-5.C (working copy)
@@ -0,0 +1,3 @@
+// PR c++/55368
+
+struct A { struct B *C,; }; // { dg-error "stray" }
Index: parser.c
===================================================================
--- parser.c (revision 193618)
+++ parser.c (working copy)
@@ -19004,6 +19003,7 @@
cp_token *initializer_token_start = NULL;
int saved_pedantic;
bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ bool seen_comma = false;
/* Check for the `__extension__' keyword. */
if (cp_parser_extension_opt (parser, &saved_pedantic))
@@ -19407,7 +19407,10 @@
parser->object_scope = NULL_TREE;
/* If it's a `,', then there are more declarators. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
- cp_lexer_consume_token (parser->lexer);
+ {
+ seen_comma = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
/* If the next token isn't a `;', then we have a parse error. */
else if (cp_lexer_next_token_is_not (parser->lexer,
CPP_SEMICOLON))
@@ -19425,6 +19428,8 @@
and issue nonsensical error messages. */
assume_semicolon = true;
}
+ else
+ seen_comma = false;
if (decl)
{
@@ -19446,6 +19451,13 @@
}
}
+ if (seen_comma)
+ {
+ cp_token *token = cp_lexer_previous_token (parser->lexer);
+ error_at (token->location,
+ "stray %<,%> at end of member declaration");
+ }
+
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
out:
parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;