Commit 71d16049 by Jason Merrill Committed by Jason Merrill

semantics.c (lambda_expr_this_capture): Fix default capture of explicit capture of 'this'.

	* semantics.c (lambda_expr_this_capture): Fix default capture
	of explicit capture of 'this'.

From-SVN: r152339
parent 1f063d10
2009-09-30 Jason Merrill <jason@redhat.com> 2009-09-30 Jason Merrill <jason@redhat.com>
* semantics.c (lambda_expr_this_capture): Fix default capture
of explicit capture of 'this'.
2009-09-30 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_lambda_expression): Don't add __ to __this. * parser.c (cp_parser_lambda_expression): Don't add __ to __this.
2009-09-30 Jason Merrill <jason@redhat.com> 2009-09-30 Jason Merrill <jason@redhat.com>
......
...@@ -5540,7 +5540,6 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) ...@@ -5540,7 +5540,6 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
current_class_type = saved_class_type; current_class_type = saved_class_type;
return member; return member;
} }
/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an /* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
...@@ -5559,6 +5558,7 @@ lambda_expr_this_capture (tree lambda) ...@@ -5559,6 +5558,7 @@ lambda_expr_this_capture (tree lambda)
{ {
tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda)); tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda));
tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE); tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE);
tree init = NULL_TREE;
/* If we are in a lambda function, we can move out until we hit: /* If we are in a lambda function, we can move out until we hit:
1. a non-lambda function, 1. a non-lambda function,
...@@ -5569,9 +5569,20 @@ lambda_expr_this_capture (tree lambda) ...@@ -5569,9 +5569,20 @@ lambda_expr_this_capture (tree lambda)
tree lambda tree lambda
= CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function)); = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));
if (LAMBDA_EXPR_THIS_CAPTURE (lambda) if (LAMBDA_EXPR_THIS_CAPTURE (lambda))
|| LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_NONE) {
break; /* An outer lambda has already captured 'this'. */
tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda);
tree lthis
= cp_build_indirect_ref (DECL_ARGUMENTS (containing_function),
"", tf_warning_or_error);
init = finish_non_static_data_member (cap, lthis, NULL_TREE);
break;
}
if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_NONE)
/* An outer lambda won't let us capture 'this'. */
break;
lambda_stack = tree_cons (NULL_TREE, lambda_stack = tree_cons (NULL_TREE,
lambda, lambda,
...@@ -5580,15 +5591,15 @@ lambda_expr_this_capture (tree lambda) ...@@ -5580,15 +5591,15 @@ lambda_expr_this_capture (tree lambda)
containing_function = decl_function_context (containing_function); containing_function = decl_function_context (containing_function);
} }
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function)) if (!init && DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function)
{ && !LAMBDA_FUNCTION_P (containing_function))
this_capture = add_default_capture (lambda_stack, /* First parameter is 'this'. */
/*id=*/get_identifier ("__this"), init = DECL_ARGUMENTS (containing_function);
/* First parameter is 'this'. */
/*initializer=*/DECL_ARGUMENTS
(containing_function));
}
if (init)
this_capture = add_default_capture (lambda_stack,
/*id=*/get_identifier ("__this"),
init);
} }
if (!this_capture) if (!this_capture)
......
...@@ -3,6 +3,16 @@ ...@@ -3,6 +3,16 @@
#include <cassert> #include <cassert>
struct A {
int i;
A(): i(42) { }
int f() {
return [this]{
return [=]{ return i; }();
}();
}
};
int main() { int main() {
int i = 1; int i = 1;
...@@ -47,6 +57,7 @@ int main() { ...@@ -47,6 +57,7 @@ int main() {
assert(i == 4); assert(i == 4);
assert (A().f() == 42);
return 0; return 0;
} }
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