re PR c++/41896 ([c++0x] Segfault because of a nested lambda function)

PR c++/41896
	* semantics.c (outer_lambda_capture_p): Revert.
	(add_capture): Only finish_member_declaration if
	we're in the lambda class.
	(register_capture_members): New.
	* cp-tree.h: Declare it.
	* parser.c (cp_parser_lambda_expression): Call it.

From-SVN: r156678
This commit is contained in:
Jason Merrill 2010-02-10 21:12:53 -05:00 committed by Jason Merrill
parent 94d7ad5fa7
commit 19030d779a
4 changed files with 34 additions and 7 deletions

View File

@ -1,3 +1,13 @@
2010-02-10 Jason Merrill <jason@redhat.com>
PR c++/41896
* semantics.c (outer_lambda_capture_p): Revert.
(add_capture): Only finish_member_declaration if
we're in the lambda class.
(register_capture_members): New.
* cp-tree.h: Declare it.
* parser.c (cp_parser_lambda_expression): Call it.
2010-02-10 Jason Merrill <jason@redhat.com>
PR c++/41896

View File

@ -5193,6 +5193,7 @@ extern tree lambda_function (tree);
extern void apply_lambda_return_type (tree, tree);
extern tree add_capture (tree, tree, tree, bool, bool);
extern tree add_default_capture (tree, tree, tree);
extern void register_capture_members (tree);
extern tree lambda_expr_this_capture (tree);
extern void maybe_add_lambda_conv_op (tree);

View File

@ -7072,6 +7072,8 @@ cp_parser_lambda_expression (cp_parser* parser)
it now. */
push_deferring_access_checks (dk_no_deferred);
cp_parser_lambda_introducer (parser, lambda_expr);
type = begin_lambda_type (lambda_expr);
record_lambda_scope (lambda_expr);
@ -7079,6 +7081,10 @@ cp_parser_lambda_expression (cp_parser* parser)
/* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
determine_visibility (TYPE_NAME (type));
/* Now that we've started the type, add the capture fields for any
explicit captures. */
register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
{
/* Inside the class, surrounding template-parameter-lists do not apply. */
unsigned int saved_num_template_parameter_lists
@ -7086,8 +7092,6 @@ cp_parser_lambda_expression (cp_parser* parser)
parser->num_template_parameter_lists = 0;
cp_parser_lambda_introducer (parser, lambda_expr);
/* By virtue of defining a local class, a lambda expression has access to
the private variables of enclosing classes. */

View File

@ -2714,9 +2714,8 @@ outer_lambda_capture_p (tree decl)
{
return (TREE_CODE (decl) == FIELD_DECL
&& LAMBDA_TYPE_P (DECL_CONTEXT (decl))
/* Using current_class_type here causes problems with uses in a
nested lambda-introducer; see 41896. */
&& DECL_CONTEXT (current_function_decl) != DECL_CONTEXT (decl));
&& (!current_class_type
|| !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type)));
}
/* ID_EXPRESSION is a representation of parsed, but unprocessed,
@ -5690,8 +5689,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
always visible. */
DECL_NORMAL_CAPTURE_P (member) = true;
/* Add it to the appropriate closure class. */
finish_member_declaration (member);
/* Add it to the appropriate closure class if we've started it. */
if (current_class_type && current_class_type == TREE_TYPE (lambda))
finish_member_declaration (member);
LAMBDA_EXPR_CAPTURE_LIST (lambda)
= tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
@ -5706,6 +5706,18 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
return member;
}
/* Register all the capture members on the list CAPTURES, which is the
LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer. */
void register_capture_members (tree captures)
{
if (captures)
{
register_capture_members (TREE_CHAIN (captures));
finish_member_declaration (TREE_PURPOSE (captures));
}
}
/* Given a FIELD_DECL decl belonging to a closure type, return a
COMPONENT_REF of it relative to the 'this' parameter of the op() for
that type. */