From patchwork Mon Nov 19 14:04:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] PR 55368 Date: Mon, 19 Nov 2012 04:04:38 -0000 From: Paolo Carlini X-Patchwork-Id: 200008 Message-Id: <50AA3C76.9060307@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill 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 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 PR c++/55368 * g++.dg/parse/struct-5.C: New. 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; 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" }