r295034 - [CodeGen][ObjC] Use the type of the captured field of the enclosing
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 13 22:46:55 PST 2017
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 {
};
}
+ at interface NSObject @end
+ at interface Foo : NSObject @end
+ at implementation Foo
+- (void)foo {
+ [&] {
+ ^{ (void)self; }();
+ }();
+}
+ at end
// ARC: attributes [[NUW]] = { noinline nounwind{{.*}} }
// MRC: attributes [[NUW]] = { noinline nounwind{{.*}} }
More information about the cfe-commits
mailing list