mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
[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:
parent
653b51a938
commit
6a8a14d217
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user