aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-28 07:23:35 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-28 07:23:35 +0000
commitfb7208119a60f68c87e7d4b6e4b87371871abb49 (patch)
treefc4c7ef351edd8f0fe03a41ed14904d5a555d6e2 /lib/CodeGen/CGObjC.cpp
parenta17f0c486d4906db055005eb91f521d9a4867e70 (diff)
Fix a couple of problems with initialization and assignment to
__block variables where the act of initialization/assignment itself causes the __block variable to be copied to the heap because the variable is of block type and is being assigned a block literal which captures the variable. rdar://problem/9814099 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136337 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r--lib/CodeGen/CGObjC.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index f81b6b75e3..2f9ff22495 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -2144,10 +2144,20 @@ CodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
llvm::Value *value = result.getPointer();
+ bool hasImmediateRetain = result.getInt();
+
+ // If we didn't emit a retained object, and the l-value is of block
+ // type, then we need to emit the block-retain immediately in case
+ // it invalidates the l-value.
+ if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
+ value = EmitARCRetainBlock(value);
+ hasImmediateRetain = true;
+ }
+
LValue lvalue = EmitLValue(e->getLHS());
// If the RHS was emitted retained, expand this.
- if (result.getInt()) {
+ if (hasImmediateRetain) {
llvm::Value *oldValue =
EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
lvalue.getAlignment(), e->getType(),