Index: clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -45,6 +45,7 @@ const char * RunLoopRunBind = "RunLoopRunM"; const char * OtherMsgBind = "OtherMessageSentM"; const char * AutoreleasePoolBind = "AutoreleasePoolM"; +const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM"; class RunLoopAutoreleaseLeakChecker : public Checker< check::ASTCodeBody> { @@ -110,6 +111,8 @@ const auto *AP = Match.getNodeAs(AutoreleasePoolBind); + const auto *OAP = + Match.getNodeAs(OtherStmtAutoreleasePoolBind); bool HasAutoreleasePool = (AP != nullptr); const auto *RL = Match.getNodeAs(RunLoopBind); @@ -120,6 +123,9 @@ if (HasAutoreleasePool && seenBefore(AP, RLR, ME)) return; + if (HasAutoreleasePool && (OAP != AP)) + return; + if (!HasAutoreleasePool && seenBefore(DeclBody, RLR, ME)) return; @@ -169,7 +175,8 @@ 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( Index: clang/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m =================================================================== --- clang/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m +++ clang/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m @@ -29,6 +29,17 @@ } } +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}}