[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

llvm-svn: 338314
This commit is contained in:
George Karpenkov 2018-07-30 22:18:21 +00:00
parent 28226e7d64
commit 81c84a9755
2 changed files with 20 additions and 4 deletions

View File

@ -45,6 +45,7 @@ const char * RunLoopBind = "NSRunLoopM";
const char * RunLoopRunBind = "RunLoopRunM";
const char * OtherMsgBind = "OtherMessageSentM";
const char * AutoreleasePoolBind = "AutoreleasePoolM";
const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM";
class RunLoopAutoreleaseLeakChecker : public Checker<check::ASTCodeBody> {
@ -111,17 +112,20 @@ static void emitDiagnostics(BoundNodes &Match,
const auto *AP =
Match.getNodeAs<ObjCAutoreleasePoolStmt>(AutoreleasePoolBind);
const auto *OAP =
Match.getNodeAs<ObjCAutoreleasePoolStmt>(OtherStmtAutoreleasePoolBind);
bool HasAutoreleasePool = (AP != nullptr);
const auto *RL = Match.getNodeAs<ObjCMessageExpr>(RunLoopBind);
const auto *RLR = Match.getNodeAs<Stmt>(RunLoopRunBind);
assert(RLR && "Run loop launch not found");
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;
if (!HasAutoreleasePool && seenBefore(DeclBody, RLR, ME))
if (HasAutoreleasePool && (OAP != AP))
return;
PathDiagnosticLocation Location = PathDiagnosticLocation::createBegin(
@ -170,7 +174,8 @@ static void
checkTempObjectsInSamePool(const Decl *D, AnalysisManager &AM, BugReporter &BR,
const RunLoopAutoreleaseLeakChecker *Chkr) {
StatementMatcher RunLoopRunM = getRunLoopRunM();
StatementMatcher OtherMessageSentM = getOtherMessageSentM();
StatementMatcher OtherMessageSentM = getOtherMessageSentM(
hasAncestor(autoreleasePoolStmt().bind(OtherStmtAutoreleasePoolBind)));
StatementMatcher RunLoopInAutorelease =
autoreleasePoolStmt(

View File

@ -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.
@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}}