]> granicus.if.org Git - clang/commitdiff
Make checkers run in deterministic order.
authorTed Kremenek <kremenek@apple.com>
Fri, 30 Oct 2009 17:47:32 +0000 (17:47 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 30 Oct 2009 17:47:32 +0000 (17:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85597 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp

index 89ca337f15e793b2d9893fc2232f950b06c91fca..90124c279daaec6e5086159e1f9cc5c089e4fc8d 100644 (file)
@@ -76,7 +76,11 @@ class GRExprEngine : public GRSubEngine {
 
   llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
 
-  llvm::DenseMap<void *, Checker*> Checkers;
+  typedef llvm::DenseMap<void *, unsigned> CheckerMap;
+  CheckerMap CheckerM;
+  
+  typedef std::vector<std::pair<void *, Checker*> >CheckersOrdered;
+  CheckersOrdered Checkers;
 
   /// BR - The BugReporter associated with this engine.  It is important that
   //   this object be placed at the very end of member variables so that its
@@ -205,13 +209,18 @@ public:
   void RegisterInternalChecks();
 
   template <typename CHECKER>
-  void registerCheck(Checker *check) {
-    Checkers[CHECKER::getTag()] = check;
+  void registerCheck(CHECKER *check) {
+    unsigned entry = Checkers.size();
+    void *tag = CHECKER::getTag();
+    Checkers.push_back(std::make_pair(tag, check));
+    CheckerM[tag] = entry;
   }
+  
+  Checker *lookupChecker(void *tag) const;
 
   template <typename CHECKER>
-  CHECKER *getChecker() {
-     return static_cast<CHECKER*>(Checkers[CHECKER::getTag()]);
+  CHECKER *getChecker() const {
+     return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
   }
 
   bool isRetStackAddr(const ExplodedNode* N) const {
index 88e67981ac1e40bfaa3f32a66936160a92254fb9..284fae8675ee0862b1a524d7bd3d6fb5ebd2eab9 100644 (file)
@@ -118,13 +118,11 @@ void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
   ExplodedNodeSet Tmp;
   ExplodedNodeSet *PrevSet = &Src;
 
-  for (llvm::DenseMap<void*, Checker*>::iterator I = Checkers.begin(), 
-         E = Checkers.end(); I != E; ++I) {
-
-    llvm::DenseMap<void*, Checker*>::iterator X = I;
-
-    ExplodedNodeSet *CurrSet = (++X == E) ? &Dst
+  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E; ++I)
+  {
+    ExplodedNodeSet *CurrSet = (I+1 == E) ? &Dst 
                                           : (PrevSet == &Tmp) ? &Src : &Tmp;
+
     CurrSet->clear();
     void *tag = I->first;
     Checker *checker = I->second;
@@ -146,7 +144,7 @@ ExplodedNode *GRExprEngine::CheckerVisitLocation(Stmt *S, ExplodedNode *Pred,
   if (Checkers.empty())
     return Pred;
 
-  for (llvm::DenseMap<void*, Checker*>::iterator I = Checkers.begin(), 
+  for (CheckersOrdered::iterator I = Checkers.begin(), 
          E = Checkers.end(); I != E; ++I) {
     Pred = I->second->CheckLocation(S, Pred, state, V, *this);
     if (!Pred)
@@ -184,8 +182,7 @@ GRExprEngine::GRExprEngine(AnalysisManager &mgr)
 GRExprEngine::~GRExprEngine() {
   BR.FlushReports();
   delete [] NSExceptionInstanceRaiseSelectors;
-  for (llvm::DenseMap<void*, Checker*>::iterator I=Checkers.begin(), 
-         E=Checkers.end(); I!=E; ++I)
+  for (CheckersOrdered::iterator I=Checkers.begin(), E=Checkers.end(); I!=E;++I)
     delete I->second;
 }
 
@@ -2860,6 +2857,15 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
   }
 }
 
+//===----------------------------------------------------------------------===//
+// Checker registration/lookup.
+//===----------------------------------------------------------------------===//
+
+Checker *GRExprEngine::lookupChecker(void *tag) const {
+  CheckerMap::iterator I = CheckerM.find(tag);
+  return (I == CheckerM.end()) ? NULL : Checkers[I->second].second;
+}
+
 //===----------------------------------------------------------------------===//
 // Visualization.
 //===----------------------------------------------------------------------===//