Fix the determination of whether a capture refers to an enclosing
authorDouglas Gregor <dgregor@apple.com>
Sat, 1 Dec 2012 01:01:09 +0000 (01:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 1 Dec 2012 01:01:09 +0000 (01:01 +0000)
scope when dealing with nested blocks. Fixes <rdar://problem/12778708>.

llvm-svn: 169065

clang/lib/Sema/SemaExpr.cpp
clang/test/CodeGenCXX/lambda-expressions.cpp

index f6defda..5b4fb29 100644 (file)
@@ -10832,13 +10832,14 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
             // actually requires the destructor.
             if (isa<ParmVarDecl>(Var))
               FinalizeVarWithDestructor(Var, Record);
-            
+
             // According to the blocks spec, the capture of a variable from
             // the stack requires a const copy constructor.  This is not true
             // of the copy/move done to move a __block variable to the heap.
-            Expr *DeclRef = new (Context) DeclRefExpr(Var, false,
+            Expr *DeclRef = new (Context) DeclRefExpr(Var, Nested,
                                                       DeclRefType.withConst(), 
                                                       VK_LValue, Loc);
+            
             ExprResult Result
               = PerformCopyInitialization(
                   InitializedEntity::InitializeBlock(Var->getLocation(),
@@ -10923,7 +10924,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
     if (BuildAndDiagnose) {
       ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType,
                                           DeclRefType, Loc,
-                                          I == N-1);
+                                          Nested);
       if (!Result.isInvalid())
         CopyExpr = Result.take();
     }
index cee4f17..19195c9 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
 
 // CHECK-NOT: @unused
 auto unused = [](int i) { return i+1; };
@@ -89,3 +89,14 @@ int g() {
 // CHECK-NEXT: ret i32
 
 // CHECK: define internal void @"_ZZ1e1ES_bEN3$_4D2Ev"
+
+// <rdar://problem/12778708>
+struct XXX {};
+void nestedCapture () {
+  XXX localKey;
+  ^() {
+    [&]() {
+      ^{ XXX k = localKey; };
+    };
+  };
+}