objective-C arc IR-gen. Retaining of strong
arguments in function prologue is done
with objc_StoreStrong to pair it with
similar objc_StoreStrong for release in function
epilogue. This is done with -O0 only.
// rdar://13145317
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175698 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index a43a383..a4d673b 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -1526,13 +1526,14 @@
// Otherwise, create a temporary to hold the value.
llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty),
D.getName() + ".addr");
- Alloc->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+ CharUnits Align = getContext().getDeclAlign(&D);
+ Alloc->setAlignment(Align.getQuantity());
DeclPtr = Alloc;
bool doStore = true;
Qualifiers qs = Ty.getQualifiers();
-
+ LValue lv = MakeAddrLValue(DeclPtr, Ty, Align);
if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
// We honor __attribute__((ns_consumed)) for types with lifetime.
// For __strong, it's handled by just skipping the initial retain;
@@ -1553,11 +1554,22 @@
}
if (lt == Qualifiers::OCL_Strong) {
- if (!isConsumed)
+ if (!isConsumed) {
+ if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+ // use objc_storeStrong(&dest, value) for retaining the
+ // object. But first, store a null into 'dest' because
+ // objc_storeStrong attempts to release its old value.
+ llvm::Value * Null = CGM.EmitNullConstant(D.getType());
+ EmitStoreOfScalar(Null, lv, /* isInitialization */ true);
+ EmitARCStoreStrongCall(lv.getAddress(), Arg, true);
+ doStore = false;
+ }
+ else
// Don't use objc_retainBlock for block pointers, because we
// don't want to Block_copy something just because we got it
// as a parameter.
- Arg = EmitARCRetainNonBlock(Arg);
+ Arg = EmitARCRetainNonBlock(Arg);
+ }
} else {
// Push the cleanup for a consumed parameter.
if (isConsumed)
@@ -1574,11 +1586,8 @@
}
// Store the initial value into the alloca.
- if (doStore) {
- LValue lv = MakeAddrLValue(DeclPtr, Ty,
- getContext().getDeclAlign(&D));
+ if (doStore)
EmitStoreOfScalar(Arg, lv, /* isInitialization */ true);
- }
}
llvm::Value *&DMEntry = LocalDeclMap[&D];