diff options
author | Nathan Froyd <froydnj@codesourcery.com> | 2010-11-06 18:41:57 +0000 |
---|---|---|
committer | Nathan Froyd <froydnj@gcc.gnu.org> | 2010-11-06 18:41:57 +0000 |
commit | 134c192bb33f87fc0b261b32d4e18a497c1e1b1c (patch) | |
tree | 85f85d6ade9121cc2106c12f318d3a31ee0c9783 /gcc/cp | |
parent | fbc7f9df71ac3c5dd63e014686ce9b3022f83f82 (diff) | |
download | gcc-134c192bb33f87fc0b261b32d4e18a497c1e1b1c.zip gcc-134c192bb33f87fc0b261b32d4e18a497c1e1b1c.tar.gz gcc-134c192bb33f87fc0b261b32d4e18a497c1e1b1c.tar.bz2 |
re PR c++/45332 (Generate clear diagnostics when a terminating semicolon is missing from a class member declaration.)
gcc/cp/
PR c++/45332
* parser.c (cp_lexer_previous_token): New function.
(cp_parser_member_declaration): Use previous token for error
messages. Assume semicolon presence rather than grovelling for
the next one.
gcc/testsuite/
PR c++/45332
* g++.dg/parse/semicolon2.C: New testcase.
* g++.dg/ext/asmspec1.C: Adjust.
* g++.dg/init/new13.C: Adjust.
* g++.dg/parse/ctor5.C: Adjust.
From-SVN: r166406
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 33 |
2 files changed, 37 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bfa4af4..784f3aa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-11-06 Nathan Froyd <froydnj@codesourcery.com> + + PR c++/45332 + * parser.c (cp_lexer_previous_token): New function. + (cp_parser_member_declaration): Use previous token for error + messages. Assume semicolon presence rather than grovelling for + the next one. + 2010-11-06 Joern Rennecke <amylaar@spamcop.net> PR middle-end/46314 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6302864..6a9e4d7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -502,6 +502,19 @@ cp_lexer_token_at (cp_lexer *lexer ATTRIBUTE_UNUSED, cp_token_position pos) return pos; } +static inline cp_token * +cp_lexer_previous_token (cp_lexer *lexer) +{ + cp_token_position tp; + + if (lexer->next_token == &eof_token) + tp = lexer->last_token - 1; + else + tp = cp_lexer_token_position (lexer, true); + + return cp_lexer_token_at (lexer, tp); +} + /* nonzero if we are presently saving tokens. */ static inline int @@ -17627,6 +17640,8 @@ cp_parser_member_declaration (cp_parser* parser) } else { + bool assume_semicolon = false; + /* See if these declarations will be friends. */ friend_p = cp_parser_friend_p (&decl_specifiers); @@ -17820,11 +17835,18 @@ cp_parser_member_declaration (cp_parser* parser) else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { - cp_parser_error (parser, "expected %<;%>"); - /* Skip tokens until we find a `;'. */ - cp_parser_skip_to_end_of_statement (parser); + /* The next token might be a ways away from where the + actual semicolon is missing. Find the previous token + and use that for our error position. */ + cp_token *token = cp_lexer_previous_token (parser->lexer); + error_at (token->location, + "expected %<;%> at end of member declaration"); - break; + /* Assume that the user meant to provide a semicolon. If + we were to cp_parser_skip_to_end_of_statement, we might + skip to a semicolon inside a member function definition + and issue nonsensical error messages. */ + assume_semicolon = true; } if (decl) @@ -17836,6 +17858,9 @@ cp_parser_member_declaration (cp_parser* parser) if (TREE_CODE (decl) == FUNCTION_DECL) cp_parser_save_default_args (parser, decl); } + + if (assume_semicolon) + return; } } |