diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-06-11 16:40:41 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-06-11 16:40:41 +0000 |
commit | 1895a0a6936001374f66adbdfcf8abe5edf912ea (patch) | |
tree | 8b5d352892a92fdbb74aa23a7241f069b6f5f824 /lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | |
parent | 9765ea9f755be50bb571100b44865f488e958d6d (diff) |
[analyzer] Add ObjCLoopChecker: objects from NSArray et al are non-nil.
While collections containing nil elements can still be iterated over in an
Objective-C for-in loop, the most common Cocoa collections -- NSArray,
NSDictionary, and NSSet -- cannot contain nil elements. This checker adds
that assumption to the analyzer state.
This was the cause of some minor false positives concerning CFRelease calls
on objects in an NSArray.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158319 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineObjC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index c8ad70ad03..45ba0449f4 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -74,7 +74,6 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, const Stmt *elem = S->getElement(); ProgramStateRef state = Pred->getState(); SVal elementV; - StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) { const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl()); @@ -86,10 +85,11 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, } ExplodedNodeSet dstLocation; - Bldr.takeNodes(Pred); evalLocation(dstLocation, S, elem, Pred, state, elementV, NULL, false); - Bldr.addNodes(dstLocation); - + + ExplodedNodeSet Tmp; + StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext); + for (ExplodedNodeSet::iterator NI = dstLocation.begin(), NE = dstLocation.end(); NI!=NE; ++NI) { Pred = *NI; @@ -126,6 +126,10 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, Bldr.generateNode(S, Pred, hasElems); Bldr.generateNode(S, Pred, noElems); } + + // Finally, run any custom checkers. + // FIXME: Eventually all pre- and post-checks should live in VisitStmt. + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); } void ExprEngine::VisitObjCMessage(const ObjCMessage &msg, |