+2007-03-03 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/15787
+ * parser.c (struct cp_parser): New IN_IF_STMT.
+ (cp_parser_statement_seq_opt): Handle an unexpected 'else',
+ returning if parsing the body of an 'if' statement or issuing an
+ error and continuing.
+ (cp_parser_selection_statement): Set IN_IF_STMT bit when parsing
+ body of 'if'.
+ (cp_parser_jump_statement): Mask new IN_IF_STMT bit.
+
2007-03-02 Simon Martin <simartin@users.sourceforge.net>
PR c++/28253
#define IN_ITERATION_STMT 2
#define IN_OMP_BLOCK 4
#define IN_OMP_FOR 8
+#define IN_IF_STMT 16
unsigned char in_statement;
/* TRUE if we are presently parsing the body of a switch statement.
|| token->type == CPP_EOF
|| token->type == CPP_PRAGMA_EOL)
break;
+
+ /* If we are in a compound statement and find 'else' then
+ something went wrong. */
+ else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
+ {
+ if (parser->in_statement & IN_IF_STMT)
+ break;
+ else
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+ error ("%<else%> without a previous %<if%>");
+ }
+ }
/* Parse the statement. */
cp_parser_statement (parser, in_statement_expr, true, NULL);
if (keyword == RID_IF)
{
bool nested_if;
+ unsigned char in_statement;
/* Add the condition. */
finish_if_stmt_cond (condition, statement);
/* Parse the then-clause. */
+ in_statement = parser->in_statement;
+ parser->in_statement |= IN_IF_STMT;
cp_parser_implicitly_scoped_statement (parser, &nested_if);
+ parser->in_statement = in_statement;
+
finish_then_clause (statement);
/* If the next token is `else', parse the else-clause. */
tree statement = error_mark_node;
cp_token *token;
enum rid keyword;
+ unsigned char in_statement;
/* Peek at the next token. */
token = cp_parser_require (parser, CPP_KEYWORD, "jump-statement");
switch (keyword)
{
case RID_BREAK:
- switch (parser->in_statement)
+ in_statement = parser->in_statement & ~IN_IF_STMT;
+ switch (in_statement)
{
case 0:
error ("break statement not within loop or switch");
break;
default:
- gcc_assert ((parser->in_statement & IN_SWITCH_STMT)
- || parser->in_statement == IN_ITERATION_STMT);
+ gcc_assert ((in_statement & IN_SWITCH_STMT)
+ || in_statement == IN_ITERATION_STMT);
statement = finish_break_stmt ();
break;
case IN_OMP_BLOCK:
break;
case RID_CONTINUE:
- switch (parser->in_statement & ~IN_SWITCH_STMT)
+ switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
{
case 0:
error ("continue statement not within a loop");