diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-11-27 23:02:53 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-11-27 23:02:53 +0000 |
commit | 82c458ea76bf8f0981e3d1b5070c0b0e5878d784 (patch) | |
tree | 1e5970626448a3183b607565ae355fa86956d644 /lib/CodeGen/CGCall.cpp | |
parent | 7aa7eb9d0221bc67e2cd564e703a2427dc212b79 (diff) |
objective-C arc: load of a __weak object happens via call to
objc_loadWeak. This retains and autorelease the weakly-refereced
object. This hidden autorelease sometimes makes __weak variable alive even
after the weak reference is erased, because the object is still referenced
by an autorelease pool. This patch overcomes this behavior by loading a
weak object via call to objc_loadWeakRetained(), followng it by objc_release
at appropriate place, thereby removing the hidden autorelease. // rdar://10849570
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168740 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 2d1d152894..c470918dde 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1740,7 +1740,12 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // Create the temporary. llvm::Value *temp = CGF.CreateTempAlloca(destType->getElementType(), "icr.temp"); - + // Loading an l-value can introduce a cleanup if the l-value is __weak, + // and that cleanup will be conditional if we can't prove that the l-value + // isn't null, so we need to register a dominating point so that the cleanups + // system will make valid IR. + CodeGenFunction::ConditionalEvaluation condEval(CGF); + // Zero-initialize it if we're not doing a copy-initialization. bool shouldCopy = CRE->shouldCopy(); if (!shouldCopy) { @@ -1749,7 +1754,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, cast<llvm::PointerType>(destType->getElementType())); CGF.Builder.CreateStore(null, temp); } - + llvm::BasicBlock *contBB = 0; // If the address is *not* known to be non-null, we need to switch. @@ -1772,6 +1777,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, llvm::BasicBlock *copyBB = CGF.createBasicBlock("icr.copy"); CGF.Builder.CreateCondBr(isNull, contBB, copyBB); CGF.EmitBlock(copyBB); + condEval.begin(CGF); } } @@ -1788,10 +1794,12 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // Use an ordinary store, not a store-to-lvalue. CGF.Builder.CreateStore(src, temp); } - + // Finish the control flow if we needed it. - if (shouldCopy && !provablyNonNull) + if (shouldCopy && !provablyNonNull) { CGF.EmitBlock(contBB); + condEval.end(CGF); + } args.addWriteback(srcAddr, srcAddrType, temp); args.add(RValue::get(finalArgument), CRE->getType()); |