summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-07-22 21:43:51 +0000
committerTed Kremenek <kremenek@apple.com>2009-07-22 21:43:51 +0000
commit49513ccaec77e64329a3388b3a3715fed828192b (patch)
tree320dccc0e1d1dda2aa6e3ec2708a1d0e0f2624a2 /clang/lib/Analysis/GRExprEngine.cpp
parent63fc4352b6a4c23ca80dac5e1b08dfcc6e747338 (diff)
downloadbcm5719-llvm-49513ccaec77e64329a3388b3a3715fed828192b.tar.gz
bcm5719-llvm-49513ccaec77e64329a3388b3a3715fed828192b.zip
Add support for registering 'Checker' objects with GRExprEngine.
Add a 'previsit' stage (that dispatches to registered Checkers) when evaluating the effects of CallExprs. llvm-svn: 76794
Diffstat (limited to 'clang/lib/Analysis/GRExprEngine.cpp')
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp53
1 files changed, 48 insertions, 5 deletions
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
index 01cc0330634..24e4cfaaa1d 100644
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ b/clang/lib/Analysis/GRExprEngine.cpp
@@ -15,6 +15,7 @@
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
+#include "clang/Analysis/PathSensitive/Checker.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
@@ -36,7 +37,7 @@ using llvm::cast;
using llvm::APSInt;
//===----------------------------------------------------------------------===//
-// Engine construction and deletion.
+// Batch auditor. DEPRECATED.
//===----------------------------------------------------------------------===//
namespace {
@@ -103,6 +104,40 @@ public:
} // end anonymous namespace
//===----------------------------------------------------------------------===//
+// Checker worklist routines.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::CheckerVisit(Stmt *S, NodeSet &Dst, NodeSet &Src,
+ bool isPrevisit) {
+
+ if (Checkers.empty()) {
+ Dst = Src;
+ return;
+ }
+
+ NodeSet Tmp;
+ NodeSet *PrevSet = &Src;
+
+ for (std::vector<Checker*>::iterator I = Checkers.begin(), E = Checkers.end();
+ I != E; ++I) {
+
+ NodeSet *CurrSet = (I+1 == E) ? &Dst : (PrevSet == &Tmp) ? &Src : &Tmp;
+ CurrSet->clear();
+ Checker *checker = *I;
+
+ for (NodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
+ NI != NE; ++NI)
+ checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, isPrevisit);
+
+ // Update which NodeSet is the current one.
+ PrevSet = CurrSet;
+ }
+
+ // Don't autotransition. The CheckerContext objects should do this
+ // automatically.
+}
+
+//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
@@ -135,6 +170,9 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
GRExprEngine::~GRExprEngine() {
BR.FlushReports();
delete [] NSExceptionInstanceRaiseSelectors;
+ for (std::vector<Checker*>::iterator I=Checkers.begin(), E=Checkers.end();
+ I!=E; ++I)
+ delete *I;
}
//===----------------------------------------------------------------------===//
@@ -1436,11 +1474,16 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
// If we reach here we have processed all of the arguments. Evaluate
// the callee expression.
-
- NodeSet DstTmp;
+ NodeSet DstTmp;
Expr* Callee = CE->getCallee()->IgnoreParens();
-
- Visit(Callee, Pred, DstTmp);
+
+ { // Enter new scope to make the lifetime of 'DstTmp2' bounded.
+ NodeSet DstTmp2;
+ Visit(Callee, Pred, DstTmp2);
+
+ // Perform the previsit of the CallExpr, storing the results in DstTmp.
+ CheckerVisit(CE, DstTmp, DstTmp2, true);
+ }
// Finally, evaluate the function call.
for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
OpenPOWER on IntegriCloud