summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-02-12 00:25:08 +0000
committerJohn McCall <rjmccall@apple.com>2013-02-12 00:25:08 +0000
commitd21cdd49471783a6743e6d449434de401aa9a2b0 (patch)
tree2abb680b15a3e7638d851ba9b1912b00ec284bd3 /clang/lib/CodeGen
parent8e24e861be1233631605d38ca6a6aa1fafd84285 (diff)
downloadbcm5719-llvm-d21cdd49471783a6743e6d449434de401aa9a2b0.tar.gz
bcm5719-llvm-d21cdd49471783a6743e6d449434de401aa9a2b0.zip
In ARC, emit non-peepholed +1s within the full-expression instead
of immediately afterwards. llvm-svn: 174922
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp36
1 files changed, 19 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 4583367bb96..b2f5aa3ef11 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -2497,12 +2497,10 @@ static TryEmitResult tryEmitARCRetainPseudoObject(CodeGenFunction &CGF,
static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
- // Look through cleanups.
- if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
- CGF.enterFullExpression(cleanups);
- CodeGenFunction::RunCleanupsScope scope(CGF);
- return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr());
- }
+ // We should *never* see a nested full-expression here, because if
+ // we fail to emit at +1, our caller must not retain after we close
+ // out the full-expression.
+ assert(!isa<ExprWithCleanups>(e));
// The desired result type, if it differs from the type of the
// ultimate opaque expression.
@@ -2654,6 +2652,13 @@ static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
/// best-effort attempt to peephole expressions that naturally produce
/// retained objects.
llvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
+ // The retain needs to happen within the full-expression.
+ if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
+ enterFullExpression(cleanups);
+ RunCleanupsScope scope(*this);
+ return EmitARCRetainScalarExpr(cleanups->getSubExpr());
+ }
+
TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
llvm::Value *value = result.getPointer();
if (!result.getInt())
@@ -2663,6 +2668,13 @@ llvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
+ // The retain needs to happen within the full-expression.
+ if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
+ enterFullExpression(cleanups);
+ RunCleanupsScope scope(*this);
+ return EmitARCRetainAutoreleaseScalarExpr(cleanups->getSubExpr());
+ }
+
TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
llvm::Value *value = result.getPointer();
if (result.getInt())
@@ -2694,17 +2706,7 @@ llvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) {
// In ARC, retain and autorelease the expression.
if (getLangOpts().ObjCAutoRefCount) {
// Do so before running any cleanups for the full-expression.
- // tryEmitARCRetainScalarExpr does make an effort to do things
- // inside cleanups, but there are crazy cases like
- // @throw A().foo;
- // where a full retain+autorelease is required and would
- // otherwise happen after the destructor for the temporary.
- if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(expr)) {
- enterFullExpression(ewc);
- expr = ewc->getSubExpr();
- }
-
- CodeGenFunction::RunCleanupsScope cleanups(*this);
+ // EmitARCRetainAutoreleaseScalarExpr does this for us.
return EmitARCRetainAutoreleaseScalarExpr(expr);
}
OpenPOWER on IntegriCloud