diff options
author | Jason Merrill <jason@redhat.com> | 2009-09-30 13:54:37 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-09-30 13:54:37 -0400 |
commit | 71d16049ff0e6a545263fc4e1295661ad0891e0c (patch) | |
tree | 80731115f2e9bf48973f1a566959902120924eed | |
parent | 1f063d1016c58854d377bea0db152694698f3694 (diff) | |
download | gcc-71d16049ff0e6a545263fc4e1295661ad0891e0c.zip gcc-71d16049ff0e6a545263fc4e1295661ad0891e0c.tar.gz gcc-71d16049ff0e6a545263fc4e1295661ad0891e0c.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C | 13 |
3 files changed, 40 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ae162d4..f617fb1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 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. 2009-09-30 Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6dec9f8..725bcc2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5540,7 +5540,6 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) current_class_type = saved_class_type; return member; - } /* 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) { tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda)); 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: 1. a non-lambda function, @@ -5569,9 +5569,20 @@ lambda_expr_this_capture (tree lambda) tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function)); - if (LAMBDA_EXPR_THIS_CAPTURE (lambda) - || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_NONE) - break; + if (LAMBDA_EXPR_THIS_CAPTURE (lambda)) + { + /* 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, @@ -5580,15 +5591,15 @@ lambda_expr_this_capture (tree lambda) containing_function = decl_function_context (containing_function); } - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function)) - { - this_capture = add_default_capture (lambda_stack, - /*id=*/get_identifier ("__this"), - /* First parameter is 'this'. */ - /*initializer=*/DECL_ARGUMENTS - (containing_function)); - } + if (!init && DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function) + && !LAMBDA_FUNCTION_P (containing_function)) + /* First parameter is 'this'. */ + init = DECL_ARGUMENTS (containing_function); + if (init) + this_capture = add_default_capture (lambda_stack, + /*id=*/get_identifier ("__this"), + init); } if (!this_capture) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C index 1689865..538775a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C @@ -3,6 +3,16 @@ #include <cassert> +struct A { + int i; + A(): i(42) { } + int f() { + return [this]{ + return [=]{ return i; }(); + }(); + } +}; + int main() { int i = 1; @@ -47,6 +57,7 @@ int main() { assert(i == 4); + assert (A().f() == 42); + return 0; } - |