OSDN Git Service

* semantics.c (lambda_expr_this_capture): Fix default capture
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Sep 2009 17:54:37 +0000 (17:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Sep 2009 17:54:37 +0000 (17:54 +0000)
of explicit capture of 'this'.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152339 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C

index ae162d4..f617fb1 100644 (file)
@@ -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>
index 6dec9f8..725bcc2 100644 (file)
@@ -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)
index 1689865..538775a 100644 (file)
@@ -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;
 }
-