forked from OSchip/llvm-project
[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 llvm-svn: 295034
This commit is contained in:
parent
ece84cd10c
commit
f1b3fc7356
clang
|
@ -318,6 +318,19 @@ static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info,
|
|||
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(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
}
|
||||
}
|
||||
|
||||
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(CodeGenFunction &CGF, BlockDecl *block) {
|
|||
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(CodeGenFunction &CGF, BlockDecl *block) {
|
|||
if (useArrayEHCleanup)
|
||||
cleanupKind = InactiveNormalAndEHCleanup;
|
||||
|
||||
CGF.pushDestroy(cleanupKind, addr, variable->getType(),
|
||||
CGF.pushDestroy(cleanupKind, addr, VT,
|
||||
destroyer, useArrayEHCleanup);
|
||||
|
||||
// Remember where that cleanup was.
|
||||
|
|
|
@ -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{{.*}} }
|
||||
|
|
Loading…
Reference in New Issue