diff options
| author | Ted Kremenek <kremenek@apple.com> | 2009-07-22 21:43:51 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2009-07-22 21:43:51 +0000 |
| commit | 49513ccaec77e64329a3388b3a3715fed828192b (patch) | |
| tree | 320dccc0e1d1dda2aa6e3ec2708a1d0e0f2624a2 /clang/lib/Analysis/GRExprEngine.cpp | |
| parent | 63fc4352b6a4c23ca80dac5e1b08dfcc6e747338 (diff) | |
| download | bcm5719-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.cpp | 53 |
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) { |

