Commit ddd039d5 by Steven Bosscher

re PR c++/29087 (More than 35000 switch cases crash cc1plus)

        PR c++/29087
        * parser.c (cp_parser_labeled_statement): Return nothing.  Do
        not take in_statement_expr and in_compound as arguments.  Rename
        to cp_parser_label_for_labeled_statement.  Parse only the label,
        not the statement.
        (cp_parser_statement): Parse the statement of a labeled-statement
        from here, using tail recursion.

From-SVN: r117026
parent cbe5ba46
2006-09-18 Steven Bosscher <steven@gcc.gnu.org>
PR c++/29087
* parser.c (cp_parser_labeled_statement): Return nothing. Do
not take in_statement_expr and in_compound as arguments. Rename
to cp_parser_label_for_labeled_statement. Parse only the label,
not the statement.
(cp_parser_statement): Parse the statement of a labeled-statement
from here, using tail recursion.
2006-09-14 Andrew Pinski <pinskia@physics.uc.edu> 2006-09-14 Andrew Pinski <pinskia@physics.uc.edu>
PR C++/29002 PR C++/29002
......
...@@ -1451,8 +1451,8 @@ static tree cp_parser_builtin_offsetof ...@@ -1451,8 +1451,8 @@ static tree cp_parser_builtin_offsetof
static void cp_parser_statement static void cp_parser_statement
(cp_parser *, tree, bool); (cp_parser *, tree, bool);
static tree cp_parser_labeled_statement static void cp_parser_label_for_labeled_statement
(cp_parser *, tree, bool); (cp_parser *);
static tree cp_parser_expression_statement static tree cp_parser_expression_statement
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_compound_statement static tree cp_parser_compound_statement
...@@ -6117,9 +6117,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6117,9 +6117,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
{ {
case RID_CASE: case RID_CASE:
case RID_DEFAULT: case RID_DEFAULT:
statement = cp_parser_labeled_statement (parser, in_statement_expr, /* Looks like a labeled-statement with a case label.
in_compound); Parse the label, and then use tail recursion to parse
break; the statement. */
cp_parser_label_for_labeled_statement (parser);
goto restart;
case RID_IF: case RID_IF:
case RID_SWITCH: case RID_SWITCH:
...@@ -6164,8 +6166,13 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6164,8 +6166,13 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
labeled-statement. */ labeled-statement. */
token = cp_lexer_peek_nth_token (parser->lexer, 2); token = cp_lexer_peek_nth_token (parser->lexer, 2);
if (token->type == CPP_COLON) if (token->type == CPP_COLON)
statement = cp_parser_labeled_statement (parser, in_statement_expr, {
in_compound); /* Looks like a labeled-statement with an ordinary label.
Parse the label, and then use tail recursion to parse
the statement. */
cp_parser_label_for_labeled_statement (parser);
goto restart;
}
} }
/* Anything that starts with a `{' must be a compound-statement. */ /* Anything that starts with a `{' must be a compound-statement. */
else if (token->type == CPP_OPEN_BRACE) else if (token->type == CPP_OPEN_BRACE)
...@@ -6215,30 +6222,23 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6215,30 +6222,23 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
SET_EXPR_LOCATION (statement, statement_location); SET_EXPR_LOCATION (statement, statement_location);
} }
/* Parse a labeled-statement. /* Parse the label for a labeled-statement, i.e.
labeled-statement: identifier :
identifier : statement case constant-expression :
case constant-expression : statement default :
default : statement
GNU Extension: GNU Extension:
case constant-expression ... constant-expression : statement
labeled-statement: When a label is parsed without errors, the label is added to the
case constant-expression ... constant-expression : statement parse tree by the finish_* functions, so this function doesn't
have to return the label. */
Returns the new CASE_LABEL_EXPR, for a `case' or `default' label.
For an ordinary label, returns a LABEL_EXPR.
IN_COMPOUND is as for cp_parser_statement: true when we're nested
inside a compound. */
static tree static void
cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr, cp_parser_label_for_labeled_statement (cp_parser* parser)
bool in_compound)
{ {
cp_token *token; cp_token *token;
tree statement = error_mark_node;
/* The next token should be an identifier. */ /* The next token should be an identifier. */
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
...@@ -6246,7 +6246,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6246,7 +6246,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
&& token->type != CPP_KEYWORD) && token->type != CPP_KEYWORD)
{ {
cp_parser_error (parser, "expected labeled-statement"); cp_parser_error (parser, "expected labeled-statement");
return error_mark_node; return;
} }
switch (token->keyword) switch (token->keyword)
...@@ -6279,7 +6279,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6279,7 +6279,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
expr_hi = NULL_TREE; expr_hi = NULL_TREE;
if (parser->in_switch_statement_p) if (parser->in_switch_statement_p)
statement = finish_case_label (expr, expr_hi); finish_case_label (expr, expr_hi);
else else
error ("case label %qE not within a switch statement", expr); error ("case label %qE not within a switch statement", expr);
} }
...@@ -6290,24 +6290,19 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr, ...@@ -6290,24 +6290,19 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
if (parser->in_switch_statement_p) if (parser->in_switch_statement_p)
statement = finish_case_label (NULL_TREE, NULL_TREE); finish_case_label (NULL_TREE, NULL_TREE);
else else
error ("case label not within a switch statement"); error ("case label not within a switch statement");
break; break;
default: default:
/* Anything else must be an ordinary label. */ /* Anything else must be an ordinary label. */
statement = finish_label_stmt (cp_parser_identifier (parser)); finish_label_stmt (cp_parser_identifier (parser));
break; break;
} }
/* Require the `:' token. */ /* Require the `:' token. */
cp_parser_require (parser, CPP_COLON, "`:'"); cp_parser_require (parser, CPP_COLON, "`:'");
/* Parse the labeled statement. */
cp_parser_statement (parser, in_statement_expr, in_compound);
/* Return the label, in the case of a `case' or `default' label. */
return statement;
} }
/* Parse an expression-statement. /* Parse an expression-statement.
......
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