aboutsummaryrefslogtreecommitdiff
path: root/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
commit72dcecc8c2f9cdd4f0faacc62676d3bb6dba4d02 (patch)
treede6136e6d9976874d71b5cffce88eb4e5cb60b4f /lib/CodeGen
parent35be4022096a7868e5c5301864d45b593e1ef442 (diff)
In ARC, emit non-peepholed +1s within the full-expression instead
of immediately afterwards. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGObjC.cpp36
1 files changed, 19 insertions, 17 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 4583367bb9..b2f5aa3ef1 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/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);
}