diff options
author | John McCall <rjmccall@apple.com> | 2011-07-27 01:07:15 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-27 01:07:15 +0000 |
commit | 538482373bba8f268b179eabde85652f630af826 (patch) | |
tree | 6ec28341ca229e59b56dde319ce3b726a6d17b1c /clang/lib/CodeGen/CGObjC.cpp | |
parent | b23dc0950b61d560b276d25654a4627dbbb666e7 (diff) | |
download | bcm5719-llvm-538482373bba8f268b179eabde85652f630af826.tar.gz bcm5719-llvm-538482373bba8f268b179eabde85652f630af826.zip |
Clean up the analysis of the collection operand to ObjC
for-in statements; specifically, make sure to close over any
temporaries or cleanups it might require. In ARC, this has
implications for the lifetime of the collection, so emit it
with a retain and release it upon exit from the loop.
rdar://problem/9817306
llvm-svn: 136204
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index c817115cbe5..f81b6b75e3f 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1020,8 +1020,16 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ ArrayType::Normal, 0); llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); - // Emit the collection pointer. - llvm::Value *Collection = EmitScalarExpr(S.getCollection()); + // Emit the collection pointer. In ARC, we do a retain. + llvm::Value *Collection; + if (getLangOptions().ObjCAutoRefCount) { + Collection = EmitARCRetainScalarExpr(S.getCollection()); + + // Enter a cleanup to do the release. + EmitObjCConsumeObject(S.getCollection()->getType(), Collection); + } else { + Collection = EmitScalarExpr(S.getCollection()); + } // Send it our message: CallArgList Args; @@ -1236,6 +1244,10 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ DI->EmitRegionEnd(Builder); } + // Leave the cleanup we entered in ARC. + if (getLangOptions().ObjCAutoRefCount) + PopCleanupBlock(); + EmitBlock(LoopEnd.getBlock()); } @@ -1967,6 +1979,12 @@ static llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF, static TryEmitResult tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) { + // Look through cleanups. + if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) { + CodeGenFunction::RunCleanupsScope scope(CGF); + return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr()); + } + // The desired result type, if it differs from the type of the // ultimate opaque expression. llvm::Type *resultType = 0; |