Commit 134c192b by Nathan Froyd Committed by Nathan Froyd

re PR c++/45332 (Generate clear diagnostics when a terminating semicolon is…

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
parent fbc7f9df
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
......
......@@ -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;
}
}
......
2010-11-06 Nathan Froyd <froydnj@codesourcery.com>
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.
2010-11-06 Janus Weil <janus@gcc.gnu.org>
PR fortran/46330
......
......@@ -3,6 +3,6 @@
struct A
{
int i __asm__(int); // { dg-error "before" }
static int j __asm__(int); // { dg-error "before" }
int i __asm__(int); // { dg-error "expected" }
static int j __asm__(int); // { dg-error "expected" }
};
......@@ -5,7 +5,7 @@
struct A
{
void* operator new(__SIZE_TYPE__) throw(X); // { dg-error "" }
void* operator new(__SIZE_TYPE__) throw(X); // { dg-error "expected|type" }
};
A* p = new A; // { dg-error "no suitable" }
A* p = new A;
......@@ -2,9 +2,9 @@
struct A
{
int i;
A() i() {} // { dg-error "expected" }
}; // { dg-error "expected" }
int i; // { dg-error "conflicts" }
A() i() {} // { dg-error "declaration" }
};
struct B
{
......
// PR c++/45332
// { dg-do compile }
class C
{
int x // { dg-error "at end of member declaration" }
const int foo() { return x; }
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment