aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp4
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp20
4 files changed, 26 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 1f137424d4..8b7eeef470 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -243,11 +243,6 @@ void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc,
case ProgramPoint::CallEnterKind: {
CallEnter CEnter = cast<CallEnter>(Loc);
- if (AnalyzedCallees)
- if (const CallExpr* CE =
- dyn_cast_or_null<CallExpr>(CEnter.getCallExpr()))
- if (const Decl *CD = CE->getCalleeDecl())
- AnalyzedCallees->insert(CD);
SubEng.processCallEnter(CEnter, Pred);
break;
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 15f47c39ae..4225c67dc7 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -55,11 +55,11 @@ STATISTIC(NumTimesRetriedWithoutInlining,
//===----------------------------------------------------------------------===//
ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
- SetOfConstDecls *VisitedCallees,
+ SetOfConstDecls *VisitedCalleesIn,
FunctionSummariesTy *FS)
: AMgr(mgr),
AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
- Engine(*this, VisitedCallees, FS),
+ Engine(*this, FS),
G(Engine.getGraph()),
StateMgr(getContext(), mgr.getStoreManagerCreator(),
mgr.getConstraintManagerCreator(), G.getAllocator(),
@@ -70,7 +70,8 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
currStmt(NULL), currStmtIdx(0), currBldrCtx(0),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", getContext())),
- ObjCGCEnabled(gcEnabled), BR(mgr, *this)
+ ObjCGCEnabled(gcEnabled), BR(mgr, *this),
+ VisitedCallees(VisitedCalleesIn)
{
if (mgr.options.eagerlyTrimExplodedGraph) {
// Enable eager node reclaimation when constructing the ExplodedGraph.
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 70350ce0c1..4313e727c5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -465,6 +465,10 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
NumInlinedCalls++;
+ // Mark the decl as visited.
+ if (VisitedCallees)
+ VisitedCallees->insert(D);
+
return true;
}
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index a10a36481d..bd643bab03 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -348,6 +348,22 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) {
}
}
+static bool shouldSkipFunction(CallGraphNode *N,
+ SmallPtrSet<CallGraphNode*,24> Visited) {
+ // We want to re-analyse the functions as top level in several cases:
+ // - The 'init' methods should be reanalyzed because
+ // ObjCNonNilReturnValueChecker assumes that '[super init]' never returns
+ // 'nil' and unless we analyze the 'init' functions as top level, we will not
+ // catch errors within defensive code.
+ // - We want to reanalyze all ObjC methods as top level to report Retain
+ // Count naming convention errors more aggressively.
+ if (isa<ObjCMethodDecl>(N->getDecl()))
+ return false;
+
+ // Otherwise, if we visited the function before, do not reanalyze it.
+ return Visited.count(N);
+}
+
void AnalysisConsumer::HandleDeclsGallGraph(const unsigned LocalTUDeclsSize) {
// Otherwise, use the Callgraph to derive the order.
// Build the Call Graph.
@@ -397,13 +413,13 @@ void AnalysisConsumer::HandleDeclsGallGraph(const unsigned LocalTUDeclsSize) {
// Push the children into the queue.
for (CallGraphNode::const_iterator CI = N->begin(),
CE = N->end(); CI != CE; ++CI) {
- if (!Visited.count(*CI))
+ if (!shouldSkipFunction(*CI, Visited))
BFSQueue.push_back(*CI);
}
// Skip the functions which have been processed already or previously
// inlined.
- if (Visited.count(N))
+ if (shouldSkipFunction(N, Visited))
continue;
// Analyze the function.