[arcmt] For:

id x = ...
@try {
 ...
} @finally {
 [x release];
}

Migrator will drop the release. It's better to change it to "x = 0" in a @finally to avoid leak when exception is thrown.

rdar://9398256

llvm-svn: 135301
This commit is contained in:
Argyrios Kyrtzidis 2011-07-15 21:11:23 +00:00
parent 653b51a938
commit 6a8a14d217
3 changed files with 45 additions and 12 deletions

View File

@ -97,10 +97,7 @@ public:
return true;
case ObjCMessageExpr::SuperInstance: {
Transaction Trans(Pass.TA);
Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
diag::err_unavailable,
diag::err_unavailable_message,
E->getSuperLoc());
clearDiagnostics(E->getSuperLoc());
if (tryRemoving(E))
return true;
Pass.TA.replace(E->getSourceRange(), "self");
@ -114,10 +111,17 @@ public:
if (!rec) return true;
Transaction Trans(Pass.TA);
Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
diag::err_unavailable,
diag::err_unavailable_message,
rec->getExprLoc());
clearDiagnostics(rec->getExprLoc());
if (E->getMethodFamily() == OMF_release &&
isRemovable(E) && isInAtFinally(E)) {
// Change the -release to "receiver = 0" in a finally to avoid a leak
// when an exception is thrown.
Pass.TA.replace(E->getSourceRange(), rec->getSourceRange());
Pass.TA.insertAfterToken(rec->getLocEnd(), " = 0");
return true;
}
if (!hasSideEffects(E, Pass.Ctx)) {
if (tryRemoving(E))
return true;
@ -128,6 +132,25 @@ public:
}
private:
void clearDiagnostics(SourceLocation loc) const {
Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
diag::err_unavailable,
diag::err_unavailable_message,
loc);
}
bool isInAtFinally(Expr *E) const {
assert(E);
Stmt *S = E;
while (S) {
if (isa<ObjCAtFinallyStmt>(S))
return true;
S = StmtMap->getParent(S);
}
return false;
}
bool isRemovable(Expr *E) const {
return Removables.count(E);
}

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: diff %t %s.result
typedef int BOOL;
@ -36,6 +36,11 @@ id IhaveSideEffect();
[IhaveSideEffect() release];
[x release], x = 0;
@try {
} @finally {
[x release];
}
}
@end

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fobjc-nonfragile-abi -fsyntax-only -x objective-c %s > %t
// RUN: diff %t %s.result
typedef int BOOL;
@ -34,6 +34,11 @@ id IhaveSideEffect();
IhaveSideEffect();
x = 0;
@try {
} @finally {
x = 0;
}
}
@end