summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2018-08-22 13:41:19 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2018-08-22 13:41:19 +0000
commit2a5e4639eaa6d85d882a60cd31d82110a8ef55d0 (patch)
treeea389085a0b7fef879c14a01b0fec27a27ba152d /clang/lib/CodeGen/CGBlocks.cpp
parent2ca72e03c3e690d618319c9563b5e28d10b9f857 (diff)
downloadbcm5719-llvm-2a5e4639eaa6d85d882a60cd31d82110a8ef55d0.tar.gz
bcm5719-llvm-2a5e4639eaa6d85d882a60cd31d82110a8ef55d0.zip
[CodeGen] Look at the type of a block capture field rather than the type
of the captured variable when determining whether the capture needs special handing when the block is copied or disposed. This fixes bugs in the handling of variables captured by a block that is nested inside a lambda that captures the variables by reference. rdar://problem/43540889 Differential Revision: https://reviews.llvm.org/D51025 llvm-svn: 340408
Diffstat (limited to 'clang/lib/CodeGen/CGBlocks.cpp')
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 8b8b6ca66f6..170e4f0c083 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -557,6 +557,10 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
CharUnits align = CGM.getPointerAlign();
maxFieldAlign = std::max(maxFieldAlign, align);
+ // Since a __block variable cannot be captured by lambdas, its type and
+ // the capture field type should always match.
+ assert(getCaptureFieldType(*CGF, CI) == variable->getType() &&
+ "capture type differs from the variable type");
layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(),
Qualifiers::OCL_None, &CI,
CGM.VoidPtrTy, variable->getType()));
@@ -570,10 +574,11 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
continue;
}
+ QualType VT = getCaptureFieldType(*CGF, CI);
+
// If we have a lifetime qualifier, honor it for capture purposes.
// That includes *not* copying it if it's __unsafe_unretained.
- Qualifiers::ObjCLifetime lifetime =
- variable->getType().getObjCLifetime();
+ Qualifiers::ObjCLifetime lifetime = VT.getObjCLifetime();
if (lifetime) {
switch (lifetime) {
case Qualifiers::OCL_None: llvm_unreachable("impossible");
@@ -587,10 +592,10 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
}
// Block pointers require copy/dispose. So do Objective-C pointers.
- } else if (variable->getType()->isObjCRetainableType()) {
+ } else if (VT->isObjCRetainableType()) {
// But honor the inert __unsafe_unretained qualifier, which doesn't
// actually make it into the type system.
- if (variable->getType()->isObjCInertUnsafeUnretainedType()) {
+ if (VT->isObjCInertUnsafeUnretainedType()) {
lifetime = Qualifiers::OCL_ExplicitNone;
} else {
info.NeedsCopyDispose = true;
@@ -602,21 +607,18 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
} else if (CI.hasCopyExpr()) {
info.NeedsCopyDispose = true;
info.HasCXXObject = true;
- if (!variable->getType()->getAsCXXRecordDecl()->isExternallyVisible())
+ if (!VT->getAsCXXRecordDecl()->isExternallyVisible())
info.CapturesNonExternalType = true;
// So do C structs that require non-trivial copy construction or
// destruction.
- } else if (variable->getType().isNonTrivialToPrimitiveCopy() ==
- QualType::PCK_Struct ||
- variable->getType().isDestructedType() ==
- QualType::DK_nontrivial_c_struct) {
+ } else if (VT.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct ||
+ VT.isDestructedType() == QualType::DK_nontrivial_c_struct) {
info.NeedsCopyDispose = true;
// And so do types with destructors.
} else if (CGM.getLangOpts().CPlusPlus) {
- if (const CXXRecordDecl *record =
- variable->getType()->getAsCXXRecordDecl()) {
+ if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) {
if (!record->hasTrivialDestructor()) {
info.HasCXXObject = true;
info.NeedsCopyDispose = true;
@@ -626,7 +628,6 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
}
}
- QualType VT = getCaptureFieldType(*CGF, CI);
CharUnits size = C.getTypeSizeInChars(VT);
CharUnits align = C.getDeclAlign(variable);
@@ -1717,10 +1718,9 @@ static void findBlockCapturedManagedEntities(
if (Capture.isConstant())
continue;
- auto CopyInfo =
- computeCopyInfoForBlockCapture(CI, Variable->getType(), LangOpts);
- auto DisposeInfo =
- computeDestroyInfoForBlockCapture(CI, Variable->getType(), LangOpts);
+ QualType VT = Capture.fieldType();
+ auto CopyInfo = computeCopyInfoForBlockCapture(CI, VT, LangOpts);
+ auto DisposeInfo = computeDestroyInfoForBlockCapture(CI, VT, LangOpts);
if (CopyInfo.first != BlockCaptureEntityKind::None ||
DisposeInfo.first != BlockCaptureEntityKind::None)
ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first,
OpenPOWER on IntegriCloud