mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 03:40:26 +08:00
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
This commit is contained in:
parent
cbe5ba46e0
commit
ddd039d56c
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
PR C++/29002
|
||||
|
@ -1451,8 +1451,8 @@ static tree cp_parser_builtin_offsetof
|
||||
|
||||
static void cp_parser_statement
|
||||
(cp_parser *, tree, bool);
|
||||
static tree cp_parser_labeled_statement
|
||||
(cp_parser *, tree, bool);
|
||||
static void cp_parser_label_for_labeled_statement
|
||||
(cp_parser *);
|
||||
static tree cp_parser_expression_statement
|
||||
(cp_parser *, tree);
|
||||
static tree cp_parser_compound_statement
|
||||
@ -6117,9 +6117,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
|
||||
{
|
||||
case RID_CASE:
|
||||
case RID_DEFAULT:
|
||||
statement = cp_parser_labeled_statement (parser, in_statement_expr,
|
||||
in_compound);
|
||||
break;
|
||||
/* Looks like a labeled-statement with a case label.
|
||||
Parse the label, and then use tail recursion to parse
|
||||
the statement. */
|
||||
cp_parser_label_for_labeled_statement (parser);
|
||||
goto restart;
|
||||
|
||||
case RID_IF:
|
||||
case RID_SWITCH:
|
||||
@ -6164,8 +6166,13 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
|
||||
labeled-statement. */
|
||||
token = cp_lexer_peek_nth_token (parser->lexer, 2);
|
||||
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. */
|
||||
else if (token->type == CPP_OPEN_BRACE)
|
||||
@ -6215,30 +6222,23 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
|
||||
SET_EXPR_LOCATION (statement, statement_location);
|
||||
}
|
||||
|
||||
/* Parse a labeled-statement.
|
||||
/* Parse the label for a labeled-statement, i.e.
|
||||
|
||||
labeled-statement:
|
||||
identifier : statement
|
||||
case constant-expression : statement
|
||||
default : statement
|
||||
identifier :
|
||||
case constant-expression :
|
||||
default :
|
||||
|
||||
GNU Extension:
|
||||
case constant-expression ... constant-expression : statement
|
||||
|
||||
labeled-statement:
|
||||
case constant-expression ... constant-expression : statement
|
||||
When a label is parsed without errors, the label is added to the
|
||||
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
|
||||
cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
|
||||
bool in_compound)
|
||||
static void
|
||||
cp_parser_label_for_labeled_statement (cp_parser* parser)
|
||||
{
|
||||
cp_token *token;
|
||||
tree statement = error_mark_node;
|
||||
|
||||
/* The next token should be an identifier. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
@ -6246,7 +6246,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
|
||||
&& token->type != CPP_KEYWORD)
|
||||
{
|
||||
cp_parser_error (parser, "expected labeled-statement");
|
||||
return error_mark_node;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (token->keyword)
|
||||
@ -6279,7 +6279,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr,
|
||||
expr_hi = NULL_TREE;
|
||||
|
||||
if (parser->in_switch_statement_p)
|
||||
statement = finish_case_label (expr, expr_hi);
|
||||
finish_case_label (expr, expr_hi);
|
||||
else
|
||||
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,
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
if (parser->in_switch_statement_p)
|
||||
statement = finish_case_label (NULL_TREE, NULL_TREE);
|
||||
finish_case_label (NULL_TREE, NULL_TREE);
|
||||
else
|
||||
error ("case label not within a switch statement");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Anything else must be an ordinary label. */
|
||||
statement = finish_label_stmt (cp_parser_identifier (parser));
|
||||
finish_label_stmt (cp_parser_identifier (parser));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Require the `:' token. */
|
||||
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user