aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-11-12 19:57:56 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-11-12 19:57:56 +0000
commit0e59b3fb64d1bce60568a79e3ff37d5f61539a43 (patch)
treeaa9b2c397865aa98457ff6c9f73d6eeff4d68475 /gcc/cp/parser.c
parentd5123baefb715e5d861535910f3c82deb8675f22 (diff)
downloadgcc-0e59b3fb64d1bce60568a79e3ff37d5f61539a43.zip
gcc-0e59b3fb64d1bce60568a79e3ff37d5f61539a43.tar.gz
gcc-0e59b3fb64d1bce60568a79e3ff37d5f61539a43.tar.bz2
decl.c (finish_case_label): Do not check that we are within a switch statement here.
* decl.c (finish_case_label): Do not check that we are within a switch statement here. * parser.c (struct cp_parser): Add in_iteration_statement_p and in_switch_statement_p. (cp_parser_new): Initialize them. (cp_parser_labeled_statement): Check validity of case labels here. (cp_parser_selection_statement): Set in_switch_statement_p. (cp_parser_iteration_statement): Set in_iteration_statement_p. (cp_parser_jump_statement): Check validity of break/continue statements here. From-SVN: r73508
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d08588f..5e24fd5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1230,6 +1230,14 @@ typedef struct cp_parser GTY(())
direct-declarator. */
bool in_declarator_p;
+ /* TRUE if we are presently parsing the body of an
+ iteration-statement. */
+ bool in_iteration_statement_p;
+
+ /* TRUE if we are presently parsing the body of a switch
+ statement. */
+ bool in_switch_statement_p;
+
/* If non-NULL, then we are parsing a construct where new type
definitions are not permitted. The string stored here will be
issued as an error message if a type is defined. */
@@ -2118,6 +2126,12 @@ cp_parser_new (void)
/* We are not processing a declarator. */
parser->in_declarator_p = false;
+ /* We are not in an iteration statement. */
+ parser->in_iteration_statement_p = false;
+
+ /* We are not in a switch statement. */
+ parser->in_switch_statement_p = false;
+
/* The unparsed function queue is empty. */
parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE);
@@ -5228,7 +5242,7 @@ static tree
cp_parser_labeled_statement (cp_parser* parser, bool in_statement_expr_p)
{
cp_token *token;
- tree statement = NULL_TREE;
+ tree statement = error_mark_node;
/* The next token should be an identifier. */
token = cp_lexer_peek_token (parser->lexer);
@@ -5251,16 +5265,20 @@ cp_parser_labeled_statement (cp_parser* parser, bool in_statement_expr_p)
expr = cp_parser_constant_expression (parser,
/*allow_non_constant_p=*/false,
NULL);
- /* Create the label. */
- statement = finish_case_label (expr, NULL_TREE);
+ if (!parser->in_switch_statement_p)
+ error ("case label `%E' not within a switch statement", expr);
+ else
+ statement = finish_case_label (expr, NULL_TREE);
}
break;
case RID_DEFAULT:
/* Consume the `default' token. */
cp_lexer_consume_token (parser->lexer);
- /* Create the label. */
- statement = finish_case_label (NULL_TREE, NULL_TREE);
+ if (!parser->in_switch_statement_p)
+ error ("case label not within a switch statement");
+ else
+ statement = finish_case_label (NULL_TREE, NULL_TREE);
break;
default:
@@ -5443,12 +5461,16 @@ cp_parser_selection_statement (cp_parser* parser)
else
{
tree body;
+ bool in_switch_statement_p;
/* Add the condition. */
finish_switch_cond (condition, statement);
/* Parse the body of the switch-statement. */
+ in_switch_statement_p = parser->in_switch_statement_p;
+ parser->in_switch_statement_p = true;
body = cp_parser_implicitly_scoped_statement (parser);
+ parser->in_switch_statement_p = in_switch_statement_p;
/* Now we're all done with the switch-statement. */
finish_switch_stmt (statement);
@@ -5564,12 +5586,18 @@ cp_parser_iteration_statement (cp_parser* parser)
cp_token *token;
enum rid keyword;
tree statement;
+ bool in_iteration_statement_p;
+
/* Peek at the next token. */
token = cp_parser_require (parser, CPP_KEYWORD, "iteration-statement");
if (!token)
return error_mark_node;
+ /* Remember whether or not we are already within an iteration
+ statement. */
+ in_iteration_statement_p = parser->in_iteration_statement_p;
+
/* See what kind of keyword it is. */
keyword = token->keyword;
switch (keyword)
@@ -5588,7 +5616,9 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Parse the dependent statement. */
+ parser->in_iteration_statement_p = true;
cp_parser_already_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
/* We're done with the while-statement. */
finish_while_stmt (statement);
}
@@ -5601,7 +5631,9 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Begin the do-statement. */
statement = begin_do_stmt ();
/* Parse the body of the do-statement. */
+ parser->in_iteration_statement_p = true;
cp_parser_implicitly_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
finish_do_body (statement);
/* Look for the `while' keyword. */
cp_parser_require_keyword (parser, RID_WHILE, "`while'");
@@ -5646,7 +5678,9 @@ cp_parser_iteration_statement (cp_parser* parser)
cp_parser_require (parser, CPP_CLOSE_PAREN, "`;'");
/* Parse the body of the for-statement. */
+ parser->in_iteration_statement_p = true;
cp_parser_already_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
/* We're done with the for-statement. */
finish_for_stmt (statement);
@@ -5727,12 +5761,25 @@ cp_parser_jump_statement (cp_parser* parser)
switch (keyword)
{
case RID_BREAK:
- statement = finish_break_stmt ();
+ if (!parser->in_switch_statement_p
+ && !parser->in_iteration_statement_p)
+ {
+ error ("break statement not within loop or switch");
+ statement = error_mark_node;
+ }
+ else
+ statement = finish_break_stmt ();
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
break;
case RID_CONTINUE:
- statement = finish_continue_stmt ();
+ if (!parser->in_iteration_statement_p)
+ {
+ error ("continue statement not within a loop");
+ statement = error_mark_node;
+ }
+ else
+ statement = finish_continue_stmt ();
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
break;