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 * 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(
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue