re PR c++/15787 (Poor error message with if and blocks)
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. testsuite/ * g++.dg/parse/else.C: New. * g++.dg/parse/else-2.C: New. From-SVN: r122505
This commit is contained in:
parent
9f1fd47476
commit
4606b05cd7
5 changed files with 66 additions and 4 deletions
|
@ -1,3 +1,14 @@
|
|||
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
|
||||
|
|
|
@ -1410,6 +1410,7 @@ typedef struct cp_parser GTY(())
|
|||
#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.
|
||||
|
@ -6538,6 +6539,19 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
|
|||
|| 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);
|
||||
|
@ -6603,12 +6617,17 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
|
|||
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. */
|
||||
|
@ -6954,6 +6973,7 @@ cp_parser_jump_statement (cp_parser* parser)
|
|||
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");
|
||||
|
@ -6965,14 +6985,15 @@ cp_parser_jump_statement (cp_parser* parser)
|
|||
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:
|
||||
|
@ -6986,7 +7007,7 @@ cp_parser_jump_statement (cp_parser* parser)
|
|||
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");
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2007-03-03 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
PR c++/15787
|
||||
* g++.dg/parse/else.C: New.
|
||||
* g++.dg/parse/else-2.C: New.
|
||||
|
||||
2007-03-03 Paul Thomas <pault@gcc.gnu.org>
|
||||
Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
|
|
11
gcc/testsuite/g++.dg/parse/else-2.C
Normal file
11
gcc/testsuite/g++.dg/parse/else-2.C
Normal file
|
@ -0,0 +1,11 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options " " }
|
||||
|
||||
int f()
|
||||
{
|
||||
|
||||
else // { dg-error "'else' without a previous 'if'" }
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
13
gcc/testsuite/g++.dg/parse/else.C
Normal file
13
gcc/testsuite/g++.dg/parse/else.C
Normal file
|
@ -0,0 +1,13 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options " " }
|
||||
|
||||
int f()
|
||||
{
|
||||
if (1)
|
||||
{
|
||||
return 1;
|
||||
else // { dg-error "expected .\}. before 'else'" }
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue