Commit 19030d77 by Jason Merrill Committed by Jason Merrill

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
parent 94d7ad5f
2010-02-10 Jason Merrill <jason@redhat.com> 2010-02-10 Jason Merrill <jason@redhat.com>
PR c++/41896 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
* semantics.c (outer_lambda_capture_p): Use current_function_decl * semantics.c (outer_lambda_capture_p): Use current_function_decl
instead of current_class_type. instead of current_class_type.
......
...@@ -5193,6 +5193,7 @@ extern tree lambda_function (tree); ...@@ -5193,6 +5193,7 @@ extern tree lambda_function (tree);
extern void apply_lambda_return_type (tree, tree); extern void apply_lambda_return_type (tree, tree);
extern tree add_capture (tree, tree, tree, bool, bool); extern tree add_capture (tree, tree, tree, bool, bool);
extern tree add_default_capture (tree, tree, tree); extern tree add_default_capture (tree, tree, tree);
extern void register_capture_members (tree);
extern tree lambda_expr_this_capture (tree); extern tree lambda_expr_this_capture (tree);
extern void maybe_add_lambda_conv_op (tree); extern void maybe_add_lambda_conv_op (tree);
......
...@@ -7072,6 +7072,8 @@ cp_parser_lambda_expression (cp_parser* parser) ...@@ -7072,6 +7072,8 @@ cp_parser_lambda_expression (cp_parser* parser)
it now. */ it now. */
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
cp_parser_lambda_introducer (parser, lambda_expr);
type = begin_lambda_type (lambda_expr); type = begin_lambda_type (lambda_expr);
record_lambda_scope (lambda_expr); record_lambda_scope (lambda_expr);
...@@ -7079,6 +7081,10 @@ cp_parser_lambda_expression (cp_parser* parser) ...@@ -7079,6 +7081,10 @@ cp_parser_lambda_expression (cp_parser* parser)
/* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
determine_visibility (TYPE_NAME (type)); 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. */ /* Inside the class, surrounding template-parameter-lists do not apply. */
unsigned int saved_num_template_parameter_lists unsigned int saved_num_template_parameter_lists
...@@ -7086,8 +7092,6 @@ cp_parser_lambda_expression (cp_parser* parser) ...@@ -7086,8 +7092,6 @@ cp_parser_lambda_expression (cp_parser* parser)
parser->num_template_parameter_lists = 0; 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 /* By virtue of defining a local class, a lambda expression has access to
the private variables of enclosing classes. */ the private variables of enclosing classes. */
......
...@@ -2714,9 +2714,8 @@ outer_lambda_capture_p (tree decl) ...@@ -2714,9 +2714,8 @@ outer_lambda_capture_p (tree decl)
{ {
return (TREE_CODE (decl) == FIELD_DECL return (TREE_CODE (decl) == FIELD_DECL
&& LAMBDA_TYPE_P (DECL_CONTEXT (decl)) && LAMBDA_TYPE_P (DECL_CONTEXT (decl))
/* Using current_class_type here causes problems with uses in a && (!current_class_type
nested lambda-introducer; see 41896. */ || !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type)));
&& DECL_CONTEXT (current_function_decl) != DECL_CONTEXT (decl));
} }
/* ID_EXPRESSION is a representation of parsed, but unprocessed, /* 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, ...@@ -5690,8 +5689,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
always visible. */ always visible. */
DECL_NORMAL_CAPTURE_P (member) = true; DECL_NORMAL_CAPTURE_P (member) = true;
/* Add it to the appropriate closure class. */ /* Add it to the appropriate closure class if we've started it. */
finish_member_declaration (member); if (current_class_type && current_class_type == TREE_TYPE (lambda))
finish_member_declaration (member);
LAMBDA_EXPR_CAPTURE_LIST (lambda) LAMBDA_EXPR_CAPTURE_LIST (lambda)
= tree_cons (member, initializer, 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, ...@@ -5706,6 +5706,18 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
return member; 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 /* 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 COMPONENT_REF of it relative to the 'this' parameter of the op() for
that type. */ that type. */
......
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