mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-09 20:31:36 +08:00
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:
parent
94d7ad5fa7
commit
19030d779a
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user