[cfe-commits] r76794 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Wed Jul 22 14:43:51 PDT 2009
Author: kremenek
Date: Wed Jul 22 16:43:51 2009
New Revision: 76794
URL: http://llvm.org/viewvc/llvm-project?rev=76794&view=rev
Log:
Add support for registering 'Checker' objects with GRExprEngine.
Add a 'previsit' stage (that dispatches to registered Checkers) when evaluating the effects of CallExprs.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Analysis/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=76794&r1=76793&r2=76794&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Wed Jul 22 16:43:51 2009
@@ -29,6 +29,7 @@
class PathDiagnosticClient;
class Diagnostic;
class ObjCForCollectionStmt;
+ class Checker;
class GRExprEngine {
public:
@@ -88,6 +89,7 @@
Selector RaiseSel;
llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
+ std::vector<Checker*> Checkers;
/// PurgeDead - Remove dead bindings before processing a statement.
bool PurgeDead;
@@ -261,6 +263,10 @@
void RegisterInternalChecks();
+ void registerCheck(Checker *check) {
+ Checkers.push_back(check);
+ }
+
bool isRetStackAddr(const NodeTy* N) const {
return N->isSink() && RetsStackAddr.count(const_cast<NodeTy*>(N)) != 0;
}
@@ -491,7 +497,10 @@
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
const void *tag = 0);
protected:
-
+ /// CheckerVisit - Dispatcher for performing checker-specific logic
+ /// at specific statements.
+ void CheckerVisit(Stmt *S, NodeSet &Dst, NodeSet &Src, bool isPrevisit);
+
/// Visit - Transfer function logic for all statements. Dispatches to
/// other functions that handle specific kinds of statements.
void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=76794&r1=76793&r2=76794&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Wed Jul 22 16:43:51 2009
@@ -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::APSInt;
//===----------------------------------------------------------------------===//
-// Engine construction and deletion.
+// Batch auditor. DEPRECATED.
//===----------------------------------------------------------------------===//
namespace {
@@ -103,6 +104,40 @@
} // 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() {
BR.FlushReports();
delete [] NSExceptionInstanceRaiseSelectors;
+ for (std::vector<Checker*>::iterator I=Checkers.begin(), E=Checkers.end();
+ I!=E; ++I)
+ delete *I;
}
//===----------------------------------------------------------------------===//
@@ -1436,11 +1474,16 @@
// 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) {
More information about the cfe-commits
mailing list