Author: ahatanak Date: Tue Feb 14 00:46:55 2017 New Revision: 295034 URL: http://llvm.org/viewvc/llvm-project?rev=295034&view=rev Log: [CodeGen][ObjC] Use the type of the captured field of the enclosing block or lambda.
This is a follow-up to r281682, which fixed a bug in computeBlockInfo where the captured VarDecl's type, rather than the captured field type of the enclosing lambda or block, was used to compute the layout of a block. This commit makes similar changes to enterBlockScope. This is necessary to correctly determine whether a block capture requires cleanup. rdar://problem/30388124 Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=295034&r1=295033&r2=295034&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Feb 14 00:46:55 2017 @@ -318,6 +318,19 @@ static void initializeForBlockHeader(Cod elementTypes.push_back(CGM.getBlockDescriptorType()); } +static QualType getCaptureFieldType(const CodeGenFunction &CGF, + const BlockDecl::Capture &CI) { + const VarDecl *VD = CI.getVariable(); + + // If the variable is captured by an enclosing block or lambda expression, + // use the type of the capture field. + if (CGF.BlockInfo && CI.isNested()) + return CGF.BlockInfo->getCapture(VD).fieldType(); + if (auto *FD = CGF.LambdaCaptureFields.lookup(VD)) + return FD->getType(); + return VD->getType(); +} + /// Compute the layout of the given block. Attempts to lay the block /// out with minimal space requirements. static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, @@ -432,15 +445,7 @@ static void computeBlockInfo(CodeGenModu } } - QualType VT = variable->getType(); - - // If the variable is captured by an enclosing block or lambda expression, - // use the type of the capture field. - if (CGF->BlockInfo && CI.isNested()) - VT = CGF->BlockInfo->getCapture(variable).fieldType(); - else if (auto *FD = CGF->LambdaCaptureFields.lookup(variable)) - VT = FD->getType(); - + QualType VT = getCaptureFieldType(*CGF, CI); CharUnits size = C.getTypeSizeInChars(VT); CharUnits align = C.getDeclAlign(variable); @@ -606,8 +611,8 @@ static void enterBlockScope(CodeGenFunct if (capture.isConstant()) continue; // Ignore objects that aren't destructed. - QualType::DestructionKind dtorKind = - variable->getType().isDestructedType(); + QualType VT = getCaptureFieldType(CGF, CI); + QualType::DestructionKind dtorKind = VT.isDestructedType(); if (dtorKind == QualType::DK_none) continue; CodeGenFunction::Destroyer *destroyer; @@ -634,7 +639,7 @@ static void enterBlockScope(CodeGenFunct if (useArrayEHCleanup) cleanupKind = InactiveNormalAndEHCleanup; - CGF.pushDestroy(cleanupKind, addr, variable->getType(), + CGF.pushDestroy(cleanupKind, addr, VT, destroyer, useArrayEHCleanup); // Remember where that cleanup was. Modified: cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm?rev=295034&r1=295033&r2=295034&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm (original) +++ cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm Tue Feb 14 00:46:55 2017 @@ -71,6 +71,10 @@ void take_block(void (^block)()) { block // ARC: %[[CAPTURE1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5 // ARC: store i32 %{{.*}}, i32* %[[CAPTURE1]] +// ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"( +// ARC-NOT: @objc_storeStrong( +// ARC: ret void + // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke" // ARC: %[[CAPTURE2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5 // ARC: store i32 %{{.*}}, i32* %[[CAPTURE2]] @@ -124,6 +128,15 @@ namespace BlockInLambda { }; } +@interface NSObject @end +@interface Foo : NSObject @end +@implementation Foo +- (void)foo { + [&] { + ^{ (void)self; }(); + }(); +} +@end // ARC: attributes [[NUW]] = { noinline nounwind{{.*}} } // MRC: attributes [[NUW]] = { noinline nounwind{{.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits