From c401755f4660d6b42ed74d53e580e4a5f8c2ee9f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 1 Dec 2012 01:01:09 +0000 Subject: [PATCH] Fix the determination of whether a capture refers to an enclosing scope when dealing with nested blocks. Fixes . llvm-svn: 169065 --- clang/lib/Sema/SemaExpr.cpp | 7 ++++--- clang/test/CodeGenCXX/lambda-expressions.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f6defdaf9f96..5b4fb297419e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10832,13 +10832,14 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, // actually requires the destructor. if (isa(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(); } diff --git a/clang/test/CodeGenCXX/lambda-expressions.cpp b/clang/test/CodeGenCXX/lambda-expressions.cpp index cee4f172a000..19195c9dd292 100644 --- a/clang/test/CodeGenCXX/lambda-expressions.cpp +++ b/clang/test/CodeGenCXX/lambda-expressions.cpp @@ -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" + +// +struct XXX {}; +void nestedCapture () { + XXX localKey; + ^() { + [&]() { + ^{ XXX k = localKey; }; + }; + }; +}