summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp14
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h1
3 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 1a57b3e6608..791a57e61f5 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -619,7 +619,13 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
// Block captures count as local values and have imprecise semantics.
// They also can't be arrays, so need to worry about that.
- if (dtorKind == QualType::DK_objc_strong_lifetime) {
+ //
+ // For const-qualified captures, emit clang.arc.use to ensure the captured
+ // object doesn't get released while we are still depending on its validity
+ // within the block.
+ if (VT.isConstQualified() && VT.getObjCLifetime() == Qualifiers::OCL_Strong)
+ destroyer = CodeGenFunction::emitARCIntrinsicUse;
+ else if (dtorKind == QualType::DK_objc_strong_lifetime) {
destroyer = CodeGenFunction::destroyARCStrongImprecise;
} else {
destroyer = CGF.getDestroyer(dtorKind);
@@ -866,6 +872,12 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
} else if (type->isReferenceType()) {
Builder.CreateStore(src.getPointer(), blockField);
+ // If type is const-qualified, copy the value into the block field.
+ } else if (type.isConstQualified() &&
+ type.getObjCLifetime() == Qualifiers::OCL_Strong) {
+ llvm::Value *value = Builder.CreateLoad(src, "captured");
+ Builder.CreateStore(value, blockField);
+
// If this is an ARC __strong block-pointer variable, don't do a
// block copy.
//
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 76e7df861f7..f4fbab3c2b8 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -2415,6 +2415,12 @@ void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
CGF.EmitARCDestroyWeak(addr);
}
+void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr,
+ QualType type) {
+ llvm::Value *value = CGF.Builder.CreateLoad(addr);
+ CGF.EmitARCIntrinsicUse(value);
+}
+
namespace {
struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup {
llvm::Value *Token;
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 1ded824ba5b..f9bc4a1bc2d 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3369,6 +3369,7 @@ public:
static Destroyer destroyARCStrongImprecise;
static Destroyer destroyARCStrongPrecise;
static Destroyer destroyARCWeak;
+ static Destroyer emitARCIntrinsicUse;
void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);
llvm::Value *EmitObjCAutoreleasePoolPush();
OpenPOWER on IntegriCloud