[cfe-commits] r171482 - in /cfe/trunk: lib/ARCMigrate/TransRetainReleaseDealloc.cpp test/ARCMT/autoreleases.m test/ARCMT/autoreleases.m.result
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Jan 4 10:29:59 PST 2013
Author: akirtzidis
Date: Fri Jan 4 12:29:59 2013
New Revision: 171482
URL: http://llvm.org/viewvc/llvm-project?rev=171482&view=rev
Log:
[arcmt] Don't error if an autoreleased variable is returned after the -autorelease.
rdar://12952025
Modified:
cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
cfe/trunk/test/ARCMT/autoreleases.m
cfe/trunk/test/ARCMT/autoreleases.m.result
Modified: cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp?rev=171482&r1=171481&r2=171482&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp Fri Jan 4 12:29:59 2013
@@ -162,13 +162,26 @@
private:
/// \brief Checks for idioms where an unused -autorelease is common.
///
- /// Currently only returns true for this idiom which is common in property
+ /// Returns true for this idiom which is common in property
/// setters:
///
/// [backingValue autorelease];
/// backingValue = [newValue retain]; // in general a +1 assign
///
+ /// For these as well:
+ ///
+ /// [[var retain] autorelease];
+ /// return var;
+ ///
bool isCommonUnusedAutorelease(ObjCMessageExpr *E) {
+ if (isPlusOneAssignAfterAutorelease(E))
+ return true;
+ if (isReturnedAfterAutorelease(E))
+ return true;
+ return false;
+ }
+
+ bool isReturnedAfterAutorelease(ObjCMessageExpr *E) {
Expr *Rec = E->getInstanceReceiver();
if (!Rec)
return false;
@@ -177,6 +190,46 @@
if (!RefD)
return false;
+ Stmt *nextStmt = getNextStmt(E);
+ if (!nextStmt)
+ return false;
+
+ // Check for "return <variable>;".
+
+ if (ReturnStmt *RetS = dyn_cast<ReturnStmt>(nextStmt))
+ return RefD == getReferencedDecl(RetS->getRetValue());
+
+ return false;
+ }
+
+ bool isPlusOneAssignAfterAutorelease(ObjCMessageExpr *E) {
+ Expr *Rec = E->getInstanceReceiver();
+ if (!Rec)
+ return false;
+
+ Decl *RefD = getReferencedDecl(Rec);
+ if (!RefD)
+ return false;
+
+ Stmt *nextStmt = getNextStmt(E);
+ if (!nextStmt)
+ return false;
+
+ // Check for "RefD = [+1 retained object];".
+
+ if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(nextStmt)) {
+ if (RefD != getReferencedDecl(Bop->getLHS()))
+ return false;
+ if (isPlusOneAssign(Bop))
+ return true;
+ }
+ return false;
+ }
+
+ Stmt *getNextStmt(Expr *E) {
+ if (!E)
+ return 0;
+
Stmt *OuterS = E, *InnerS;
do {
InnerS = OuterS;
@@ -187,9 +240,7 @@
isa<ExprWithCleanups>(OuterS)));
if (!OuterS)
- return false;
-
- // Find next statement after the -autorelease.
+ return 0;
Stmt::child_iterator currChildS = OuterS->child_begin();
Stmt::child_iterator childE = OuterS->child_end();
@@ -198,25 +249,15 @@
break;
}
if (currChildS == childE)
- return false;
+ return 0;
++currChildS;
if (currChildS == childE)
- return false;
+ return 0;
Stmt *nextStmt = *currChildS;
if (!nextStmt)
- return false;
- nextStmt = nextStmt->IgnoreImplicit();
-
- // Check for "RefD = [+1 retained object];".
-
- if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(nextStmt)) {
- if (RefD != getReferencedDecl(Bop->getLHS()))
- return false;
- if (isPlusOneAssign(Bop))
- return true;
- }
- return false;
+ return 0;
+ return nextStmt->IgnoreImplicit();
}
Decl *getReferencedDecl(Expr *E) {
@@ -224,6 +265,17 @@
return 0;
E = E->IgnoreParenCasts();
+ if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ switch (ME->getMethodFamily()) {
+ case OMF_copy:
+ case OMF_autorelease:
+ case OMF_release:
+ case OMF_retain:
+ return getReferencedDecl(ME->getInstanceReceiver());
+ default:
+ return 0;
+ }
+ }
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
return DRE->getDecl();
if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
Modified: cfe/trunk/test/ARCMT/autoreleases.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/autoreleases.m?rev=171482&r1=171481&r2=171482&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/autoreleases.m (original)
+++ cfe/trunk/test/ARCMT/autoreleases.m Fri Jan 4 12:29:59 2013
@@ -64,3 +64,8 @@
[prevVal autorelease];
prevVal = [newVal retain];
}
+
+id test2(A* val) {
+ [[val retain] autorelease];
+ return val;
+}
Modified: cfe/trunk/test/ARCMT/autoreleases.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/autoreleases.m.result?rev=171482&r1=171481&r2=171482&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/autoreleases.m.result (original)
+++ cfe/trunk/test/ARCMT/autoreleases.m.result Fri Jan 4 12:29:59 2013
@@ -60,3 +60,7 @@
void test(A *prevVal, A *newVal) {
prevVal = newVal;
}
+
+id test2(A* val) {
+ return val;
+}
More information about the cfe-commits
mailing list