From 29a93f810ae5277446f610e8b6cdf0985febb989 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 16 May 2012 16:50:20 +0000 Subject: [PATCH] Fix code generation of variables reference expressions when mixing blocks and lambdas, based heavily on a patch from Meador Inge. Fixes PR12746 / . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156925 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 2 +- lib/Sema/SemaExpr.cpp | 2 +- .../expr/expr.prim/expr.prim.lambda/blocks.mm | 22 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index dad8e7ea7c..47c6c48018 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -698,7 +698,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // Compute the address of the thing we're going to move into the // block literal. llvm::Value *src; - if (ci->isNested()) { + if (BlockInfo && ci->isNested()) { // We need to use the capture from the enclosing block. const CGBlockInfo::Capture &enclosingCapture = BlockInfo->getCapture(variable); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e81787d5a4..440382bb5a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10069,7 +10069,7 @@ 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, false, DeclRefType, + Expr *Ref = new (S.Context) DeclRefExpr(Var, true, DeclRefType, VK_LValue, Loc); Var->setReferenced(true); Var->setUsed(true); 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 0c3fdb2d80..941443a0d6 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm @@ -86,3 +86,25 @@ 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(); + } +} -- 2.40.0