re PR c++/46124 ([C++0x] ICE: tree check: expected var_decl or function_decl, have error_mark in cp_parser_lambda_declarator_opt, at cp/parser.c:7817 on invalid lambda function)

PR c++/46124
	* parser.c (cp_parser_lambda_expression): Improve error recovery.
	(cp_parser_lambda_declarator_opt): Likewise.  Return bool.

From-SVN: r174386
This commit is contained in:
Jason Merrill 2011-05-28 18:01:38 -04:00 committed by Jason Merrill
parent 32da2be4cc
commit 0fa1a986d7
4 changed files with 36 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2011-05-28 Jason Merrill <jason@redhat.com>
PR c++/46124
* parser.c (cp_parser_lambda_expression): Improve error recovery.
(cp_parser_lambda_declarator_opt): Likewise. Return bool.
2011-05-27 Jason Merrill <jason@redhat.com>
PR c++/47277

View File

@ -1580,7 +1580,7 @@ static tree cp_parser_lambda_expression
(cp_parser *);
static void cp_parser_lambda_introducer
(cp_parser *, tree);
static void cp_parser_lambda_declarator_opt
static bool cp_parser_lambda_declarator_opt
(cp_parser *, tree);
static void cp_parser_lambda_body
(cp_parser *, tree);
@ -7347,6 +7347,7 @@ cp_parser_lambda_expression (cp_parser* parser)
{
tree lambda_expr = build_lambda_expr ();
tree type;
bool ok;
LAMBDA_EXPR_LOCATION (lambda_expr)
= cp_lexer_peek_token (parser->lexer)->location;
@ -7382,9 +7383,12 @@ cp_parser_lambda_expression (cp_parser* parser)
/* By virtue of defining a local class, a lambda expression has access to
the private variables of enclosing classes. */
cp_parser_lambda_declarator_opt (parser, lambda_expr);
ok = cp_parser_lambda_declarator_opt (parser, lambda_expr);
if (ok)
cp_parser_lambda_body (parser, lambda_expr);
else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
cp_parser_skip_to_end_of_block_or_statement (parser);
/* The capture list was built up in reverse order; fix that now. */
{
@ -7418,6 +7422,7 @@ cp_parser_lambda_expression (cp_parser* parser)
LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
}
if (ok)
maybe_add_lambda_conv_op (type);
type = finish_struct (type, /*attributes=*/NULL_TREE);
@ -7427,7 +7432,10 @@ cp_parser_lambda_expression (cp_parser* parser)
pop_deferring_access_checks ();
if (ok)
return build_lambda_object (lambda_expr);
else
return error_mark_node;
}
/* Parse the beginning of a lambda expression.
@ -7592,7 +7600,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
LAMBDA_EXPR is the current representation of the lambda expression. */
static void
static bool
cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
{
/* 5.1.1.4 of the standard says:
@ -7688,12 +7696,17 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
fco = grokmethod (&return_type_specs,
declarator,
attributes);
if (fco != error_mark_node)
{
DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
DECL_ARTIFICIAL (fco) = 1;
}
finish_member_declaration (fco);
obstack_free (&declarator_obstack, p);
return (fco != error_mark_node);
}
}

View File

@ -1,3 +1,7 @@
2011-05-28 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/lambda/lambda-syntax1.C: New.
2011-05-27 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/enum18.C: Adjust.

View File

@ -0,0 +1,5 @@
// PR c++/46124
// { dg-options -std=c++0x }
void foo() { [] () -> void (); } // { dg-error "returning a function" }
// { dg-error "expected .\{" "" { target *-*-* } 4 }