diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 440382bb5a..67b60fad51 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10040,7 +10040,8 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, VarDecl *Var, QualType FieldType, QualType DeclRefType, - SourceLocation Loc) { + SourceLocation Loc, + bool RefersToEnclosingLocal) { CXXRecordDecl *Lambda = LSI->Lambda; // Build the non-static data member. @@ -10069,8 +10070,8 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, // C++ [expr.prim.labda]p12: // An entity captured by a lambda-expression is odr-used (3.2) in // the scope containing the lambda-expression. - Expr *Ref = new (S.Context) DeclRefExpr(Var, true, DeclRefType, - VK_LValue, Loc); + Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, + DeclRefType, VK_LValue, Loc); Var->setReferenced(true); Var->setUsed(true); @@ -10413,7 +10414,8 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, Expr *CopyExpr = 0; if (BuildAndDiagnose) { ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType, - DeclRefType, Loc); + DeclRefType, Loc, + I == N-1); if (!Result.isInvalid()) CopyExpr = Result.take(); } diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm new file mode 100644 index 0000000000..9adecd0ee3 --- /dev/null +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -emit-llvm -o - -triple x86_64-apple-darwin11.3 %s | FileCheck %s + +namespace PR12746 { + // CHECK: define zeroext i1 @_ZN7PR127462f1EPi + bool f1(int *x) { + // CHECK: store i8* bitcast (i1 (i8*)* @__f1_block_invoke_0 to i8*) + bool (^outer)() = ^ { + auto inner = [&]() -> bool { + return x == 0; + }; + return inner(); + }; + return outer(); + } + + // CHECK: define internal zeroext i1 @__f1_block_invoke_0 + // CHECK: call zeroext i1 @"_ZNK7PR127462f119__f1_block_invoke_03$_0clEv" + + bool f2(int *x) { + auto outer = [&]() -> bool { + bool (^inner)() = ^ { + return x == 0; + }; + return inner(); + }; + return outer(); + } +} + diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm index 941443a0d6..0c3fdb2d80 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm @@ -86,25 +86,3 @@ namespace overloading { int &ir = accept_lambda_conv([](int x) { return x + 1; }); } } - -namespace PR12746 { - bool f1(int *x) { - bool (^outer)() = ^ { - auto inner = [&]() -> bool { - return x == 0; - }; - return inner(); - }; - return outer(); - } - - bool f2(int *x) { - auto outer = [&]() -> bool { - bool (^inner)() = ^ { - return x == 0; - }; - return inner(); - }; - return outer(); - } -}