summaryrefslogtreecommitdiffstats
path: root/clang/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
commitb726a5572993e2b12442a6eed7337a311b7ebc28 (patch)
tree3b6821dd460630a23e300f2c7529730893b42f91 /clang/lib/CodeGen/CGObjC.cpp
parent3255d1d25fb3324b3be6b8612e60eb59f96aaa4c (diff)
downloadbcm5719-llvm-b726a5572993e2b12442a6eed7337a311b7ebc28.tar.gz
bcm5719-llvm-b726a5572993e2b12442a6eed7337a311b7ebc28.zip
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 llvm-svn: 136337
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index f81b6b75e3f..2f9ff224959 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/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(),
OpenPOWER on IntegriCloud