From: Eli Friedman Date: Fri, 12 Jul 2013 22:05:26 +0000 (+0000) Subject: Compute 'this' correctly for block in lambda. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c1b8d095c18c3f55d662c49e59f7a934ae7e9440;p=clang Compute 'this' correctly for block in lambda. Using CurFuncDecl is both correct and simple compared to crawling the DeclContexts of the block. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186210 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 8cc4891cc7..eb1afa6955 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -355,14 +355,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // First, 'this'. if (block->capturesCXXThis()) { - const DeclContext *DC = block->getDeclContext(); - for (; isa(DC); DC = cast(DC)->getDeclContext()) - ; - QualType thisType; - if (const CXXRecordDecl *RD = dyn_cast(DC)) - thisType = C.getPointerType(C.getRecordType(RD)); - else - thisType = cast(DC)->getThisType(C); + assert(CGF && CGF->CurFuncDecl && isa(CGF->CurFuncDecl) && + "Can't capture 'this' outside a method"); + QualType thisType = cast(CGF->CurFuncDecl)->getThisType(C); llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); std::pair tinfo diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm index acb8efb4b5..84ebeb9d7b 100644 --- a/test/CodeGenObjCXX/lambda-expressions.mm +++ b/test/CodeGenObjCXX/lambda-expressions.mm @@ -60,6 +60,12 @@ void take_block(void (^block)()) { block(); } } @end +// Check lines for BlockInLambda test below +// ARC: define internal i32 @___ZZN13BlockInLambda1X1fEvENKUlvE_clEv_block_invoke +// ARC: [[Y:%.*]] = getelementptr inbounds %"struct.BlockInLambda::X"* {{.*}}, i32 0, i32 1 +// ARC-NEXT: [[YVAL:%.*]] = load i32* [[Y]], align 4 +// ARC-NEXT: ret i32 [[YVAL]] + typedef int (^fptr)(); template struct StaticMembers { static fptr f; @@ -69,6 +75,18 @@ fptr StaticMembers::f = [] { auto f = []{return 5;}; return fptr(f); }(); template fptr StaticMembers::f; // ARC: define linkonce_odr i32 ()* @_ZZNK13StaticMembersIfE1fMUlvE_clEvENKUlvE_cvU13block_pointerFivEEv +namespace BlockInLambda { + struct X { + int x,y; + void f() { + [this]{return ^{return y;}();}(); + }; + }; + void g(X& x) { + x.f(); + }; +} + // ARC: attributes [[NUW]] = { nounwind{{.*}} } // MRC: attributes [[NUW]] = { nounwind{{.*}} }