aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathan Froyd <froydnj@codesourcery.com>2010-11-06 18:41:57 +0000
committerNathan Froyd <froydnj@gcc.gnu.org>2010-11-06 18:41:57 +0000
commit134c192bb33f87fc0b261b32d4e18a497c1e1b1c (patch)
tree85f85d6ade9121cc2106c12f318d3a31ee0c9783 /gcc/cp
parentfbc7f9df71ac3c5dd63e014686ce9b3022f83f82 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/parser.c33
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;
}
}