mirror of https://github.com/microsoft/clang.git
[analyzer] Bugfix for autorelease + main run loop leak checker
Do not warn when the other message-send-expression is correctly wrapped in a different autorelease pool. Differential Revision: https://reviews.llvm.org/D49921 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338314 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
384410eb05
commit
fdff255e9d
|
@ -45,6 +45,7 @@ const char * RunLoopBind = "NSRunLoopM";
|
||||||
const char * RunLoopRunBind = "RunLoopRunM";
|
const char * RunLoopRunBind = "RunLoopRunM";
|
||||||
const char * OtherMsgBind = "OtherMessageSentM";
|
const char * OtherMsgBind = "OtherMessageSentM";
|
||||||
const char * AutoreleasePoolBind = "AutoreleasePoolM";
|
const char * AutoreleasePoolBind = "AutoreleasePoolM";
|
||||||
|
const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM";
|
||||||
|
|
||||||
class RunLoopAutoreleaseLeakChecker : public Checker<check::ASTCodeBody> {
|
class RunLoopAutoreleaseLeakChecker : public Checker<check::ASTCodeBody> {
|
||||||
|
|
||||||
|
@ -111,17 +112,20 @@ static void emitDiagnostics(BoundNodes &Match,
|
||||||
|
|
||||||
const auto *AP =
|
const auto *AP =
|
||||||
Match.getNodeAs<ObjCAutoreleasePoolStmt>(AutoreleasePoolBind);
|
Match.getNodeAs<ObjCAutoreleasePoolStmt>(AutoreleasePoolBind);
|
||||||
|
const auto *OAP =
|
||||||
|
Match.getNodeAs<ObjCAutoreleasePoolStmt>(OtherStmtAutoreleasePoolBind);
|
||||||
bool HasAutoreleasePool = (AP != nullptr);
|
bool HasAutoreleasePool = (AP != nullptr);
|
||||||
|
|
||||||
const auto *RL = Match.getNodeAs<ObjCMessageExpr>(RunLoopBind);
|
const auto *RL = Match.getNodeAs<ObjCMessageExpr>(RunLoopBind);
|
||||||
const auto *RLR = Match.getNodeAs<Stmt>(RunLoopRunBind);
|
const auto *RLR = Match.getNodeAs<Stmt>(RunLoopRunBind);
|
||||||
assert(RLR && "Run loop launch not found");
|
assert(RLR && "Run loop launch not found");
|
||||||
|
|
||||||
assert(ME != RLR);
|
assert(ME != RLR);
|
||||||
if (HasAutoreleasePool && seenBefore(AP, RLR, ME))
|
|
||||||
|
// Launch of run loop occurs before the message-sent expression is seen.
|
||||||
|
if (seenBefore(DeclBody, RLR, ME))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasAutoreleasePool && seenBefore(DeclBody, RLR, ME))
|
if (HasAutoreleasePool && (OAP != AP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PathDiagnosticLocation Location = PathDiagnosticLocation::createBegin(
|
PathDiagnosticLocation Location = PathDiagnosticLocation::createBegin(
|
||||||
|
@ -170,7 +174,8 @@ static void
|
||||||
checkTempObjectsInSamePool(const Decl *D, AnalysisManager &AM, BugReporter &BR,
|
checkTempObjectsInSamePool(const Decl *D, AnalysisManager &AM, BugReporter &BR,
|
||||||
const RunLoopAutoreleaseLeakChecker *Chkr) {
|
const RunLoopAutoreleaseLeakChecker *Chkr) {
|
||||||
StatementMatcher RunLoopRunM = getRunLoopRunM();
|
StatementMatcher RunLoopRunM = getRunLoopRunM();
|
||||||
StatementMatcher OtherMessageSentM = getOtherMessageSentM();
|
StatementMatcher OtherMessageSentM = getOtherMessageSentM(
|
||||||
|
hasAncestor(autoreleasePoolStmt().bind(OtherStmtAutoreleasePoolBind)));
|
||||||
|
|
||||||
StatementMatcher RunLoopInAutorelease =
|
StatementMatcher RunLoopInAutorelease =
|
||||||
autoreleasePoolStmt(
|
autoreleasePoolStmt(
|
||||||
|
|
|
@ -29,6 +29,17 @@ void runloop_init_before() { // Warning: object created before the loop.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runloop_init_before_separate_pool() { // No warning: separate autorelease pool.
|
||||||
|
@autoreleasepool {
|
||||||
|
NSObject *object;
|
||||||
|
@autoreleasepool {
|
||||||
|
object = [[NSObject alloc] init]; // no-warning
|
||||||
|
}
|
||||||
|
(void) object;
|
||||||
|
[[NSRunLoop mainRunLoop] run];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void xpcmain_init_before() { // Warning: object created before the loop.
|
void xpcmain_init_before() { // Warning: object created before the loop.
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of xpc_main may never get released; consider moving them to a separate autorelease pool}}
|
NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of xpc_main may never get released; consider moving them to a separate autorelease pool}}
|
||||||
|
|
Loading…
Reference in New Issue