aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/CheckerManager.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-23 19:38:39 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-23 19:38:39 +0000
commite1bfb7ae0dd0762c88e1fd94746e973c37f2e04e (patch)
tree4409bfc07098e23f4f755fa40fdd501771b88964 /lib/StaticAnalyzer/Core/CheckerManager.cpp
parent2ea40c0db7d6e281fad49f8c34335ef04c5b9b84 (diff)
[analyzer] Migrate ChrootChecker to CheckerV2.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126324 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CheckerManager.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp67
1 files changed, 64 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 0ff29757a6..ba52c4014d 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -66,7 +66,9 @@ static void runPathSensitiveCheckers(CHECK_CTX checkCtx,
ExplodedNodeSet &Dst,
ExplodedNodeSet &Src) {
- if (checkCtx.Checkers.empty()) {
+ typename CHECK_CTX::CheckersTy::const_iterator
+ I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
+ if (I == E) {
Dst.insert(Src);
return;
}
@@ -74,8 +76,7 @@ static void runPathSensitiveCheckers(CHECK_CTX checkCtx,
ExplodedNodeSet Tmp;
ExplodedNodeSet *PrevSet = &Src;
- for (typename CHECK_CTX::CheckersTy::const_iterator
- I= checkCtx.Checkers.begin(), E= checkCtx.Checkers.end(); I!=E; ++I) {
+ for (; I != E; ++I) {
ExplodedNodeSet *CurrSet = 0;
if (I+1 == E)
CurrSet = &Dst;
@@ -101,6 +102,9 @@ namespace {
const Stmt *S;
ExprEngine &Eng;
+ CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
+ CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
+
CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
const Stmt *s, ExprEngine &eng)
: IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { }
@@ -135,6 +139,9 @@ namespace {
const ObjCMessage &Msg;
ExprEngine &Eng;
+ CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
+ CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
+
CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
const ObjCMessage &msg, ExprEngine &eng)
: IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
@@ -173,6 +180,9 @@ namespace {
const GRState *State;
ExprEngine &Eng;
+ CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
+ CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
+
CheckLocationContext(const CheckersTy &checkers,
SVal loc, bool isLoad, const Stmt *s,
const GRState *state, ExprEngine &eng)
@@ -207,6 +217,50 @@ void CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
EndAnalysisCheckers[i](G, BR, Eng);
}
+/// \brief Run checkers for evaluating a call.
+/// Only one checker will evaluate the call.
+void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
+ const ExplodedNodeSet &Src,
+ const CallExpr *CE,
+ ExprEngine &Eng,
+ GraphExpander *defaultEval) {
+ if (EvalCallCheckers.empty() && defaultEval == 0) {
+ Dst.insert(Src);
+ return;
+ }
+
+ for (ExplodedNodeSet::iterator
+ NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
+
+ ExplodedNode *Pred = *NI;
+ bool anyEvaluated = false;
+ for (std::vector<EvalCallFunc>::iterator
+ EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
+ EI != EE; ++EI) {
+ ExplodedNodeSet checkDst;
+ CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, EI->Checker,
+ ProgramPoint::PostStmtKind, 0, CE);
+ bool evaluated = (*EI)(CE, C);
+ assert(!(evaluated && anyEvaluated)
+ && "There are more than one checkers evaluating the call");
+ if (evaluated) {
+ anyEvaluated = true;
+ Dst.insert(checkDst);
+#ifdef NDEBUG
+ break; // on release don't check that no other checker also evals.
+#endif
+ }
+ }
+
+ if (!anyEvaluated) {
+ if (defaultEval)
+ defaultEval->expandGraph(Dst, Pred);
+ else
+ Dst.insert(Pred);
+ }
+ }
+}
+
void CheckerManager::registerCheckersToEngine(ExprEngine &eng) {
for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
Funcs[i](eng);
@@ -256,6 +310,10 @@ void CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
EndAnalysisCheckers.push_back(checkfn);
}
+void CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) {
+ EvalCallCheckers.push_back(checkfn);
+}
+
//===----------------------------------------------------------------------===//
// Implementation details.
//===----------------------------------------------------------------------===//
@@ -290,3 +348,6 @@ CheckerManager::~CheckerManager() {
// Anchor for the vtable.
CheckerProvider::~CheckerProvider() { }
+
+// Anchor for the vtable.
+GraphExpander::~GraphExpander() { }