summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-30 23:42:02 +0000
committerAnna Zaks <ganna@apple.com>2012-08-30 23:42:02 +0000
commita8017eca1afafbeb3705d53efebdc783b1bd9e14 (patch)
treeb7fabdb8b730f20cadac686e533de60765e40a20 /clang/lib
parentcc61f87cf730fec6785dc492fb6c71bc17c8f56b (diff)
downloadbcm5719-llvm-a8017eca1afafbeb3705d53efebdc783b1bd9e14.tar.gz
bcm5719-llvm-a8017eca1afafbeb3705d53efebdc783b1bd9e14.zip
[analyzer] Refactor the logic that determines if a functions should be
reanalyzed. The policy on what to reanalyze should be in AnalysisConsumer with the rest of visitation order logic. There is no reason why ExprEngine needs to pass the Visited set to CoreEngine, it can populate it itself. llvm-svn: 162957
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/CoreEngine.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp20
4 files changed, 26 insertions, 10 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 1f137424d45..8b7eeef470c 100644
--- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 15f47c39ae5..4225c67dc70 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 70350ce0c1c..4313e727c51 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index a10a36481d1..bd643bab037 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/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.
OpenPOWER on IntegriCloud