From 384410eb0571efc2d7d591ad3cf5efeead61ef1c Mon Sep 17 00:00:00 2001 From: George Karpenkov Date: Mon, 30 Jul 2018 21:44:15 +0000 Subject: [PATCH] [analyzer] Fix crash in RunLoopAutoreleaseChecker on empty children Differential Revision: https://reviews.llvm.org/D50012 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338312 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/RunLoopAutoreleaseLeakChecker.cpp | 5 +++-- .../Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m | 11 ++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp index 64b61a0213..5c57854419 100644 --- a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -46,8 +46,7 @@ const char * RunLoopRunBind = "RunLoopRunM"; const char * OtherMsgBind = "OtherMessageSentM"; const char * AutoreleasePoolBind = "AutoreleasePoolM"; -class RunLoopAutoreleaseLeakChecker : public Checker< - check::ASTCodeBody> { +class RunLoopAutoreleaseLeakChecker : public Checker { public: void checkASTCodeBody(const Decl *D, @@ -66,6 +65,8 @@ static TriBoolTy seenBeforeRec(const Stmt *Parent, const Stmt *A, const Stmt *B, MemoizationMapTy &Memoization) { for (const Stmt *C : Parent->children()) { + if (!C) continue; + if (C == A) return true; diff --git a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m index 4dde40e210..32fc2206a3 100644 --- a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m +++ b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m @@ -43,7 +43,7 @@ void runloop_init_before_two_objects() { // Warning: object created before the l NSObject *object2 = [[NSObject alloc] init]; // no-warning, warning on the first one is enough. (void) object; (void) object2; - [[NSRunLoop mainRunLoop] run]; + [[NSRunLoop mainRunLoop] run]; } } @@ -61,6 +61,15 @@ void runloop_init_after() { // No warning: objects created after the loop } } +void no_crash_on_empty_children() { + @autoreleasepool { + for (;;) {} + NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} + [[NSRunLoop mainRunLoop] run]; + (void) object; + } +} + #endif #ifdef AP1 -- 2.40.0