[cfe-commits] r142827 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h lib/StaticAnalyzer/Core/CheckerContext.cpp lib/StaticAnalyzer/Core/CheckerManager.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp

Anna Zaks ganna at apple.com
Mon Oct 24 11:25:59 PDT 2011


Author: zaks
Date: Mon Oct 24 13:25:58 2011
New Revision: 142827

URL: http://llvm.org/viewvc/llvm-project?rev=142827&view=rev
Log:
[analyzer] Use a temporary builder in CheckerContext.

First step toward removing the global Stmt builder. Added several transitional methods (like takeNodes/addNodes).
+ Stop early if the set of exploded nodes for the next iteration is empty.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Mon Oct 24 13:25:58 2011
@@ -23,29 +23,24 @@
 namespace ento {
 
 class CheckerContext {
-  ExplodedNodeSet &Dst;
   ExprEngine &Eng;
   ExplodedNode *Pred;
   const ProgramPoint Location;
   const ProgramState *ST;
-  const unsigned size;
   NodeBuilder &NB;
 public:
   bool *respondsToCallback;
 public:
-  CheckerContext(ExplodedNodeSet &dst,
-                 NodeBuilder &builder,
+  CheckerContext(NodeBuilder &builder,
                  ExprEngine &eng,
                  ExplodedNode *pred,
                  const ProgramPoint &loc,
                  bool *respondsToCB = 0,
                  const ProgramState *st = 0)
-    : Dst(dst),
-      Eng(eng),
+    : Eng(eng),
       Pred(pred),
       Location(loc),
       ST(st),
-      size(Dst.size()),
       NB(builder),
       respondsToCallback(respondsToCB) {
     assert(!(ST && ST != Pred->getState()));
@@ -153,7 +148,6 @@
                                  bool markAsSink,
                                  ExplodedNode *pred = 0,
                                  const ProgramPointTag *tag = 0) {
-
     ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location,
                                         state,
                                         pred ? pred : Pred, markAsSink);

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Mon Oct 24 13:25:58 2011
@@ -202,6 +202,14 @@
     return true;
   }
 
+  bool haveNoSinksInFrontier() {
+    for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
+      if ((*I)->isSink())
+        return false;
+    }
+    return true;
+  }
+
   /// Allow subclasses to finalize results before result_begin() is executed.
   virtual void finalizeResults() {}
   
@@ -214,13 +222,19 @@
   NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
               const NodeBuilderContext &Ctx, bool F = true)
     : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
-    Frontier.insert(SrcNode);
+    assert(DstSet.empty());
+    Frontier.Add(SrcNode);
   }
 
   NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
               const NodeBuilderContext &Ctx, bool F = true)
     : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+    assert(DstSet.empty());
+    //assert(!SrcSet.empty());
+
     Frontier.insert(SrcSet);
+
+    assert(haveNoSinksInFrontier());
   }
 
   virtual ~NodeBuilder() {}
@@ -365,13 +379,23 @@
     return N;
   }
 
-  void importNodesFromBuilder(const NodeBuilder &NB) {
-    ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.C.ContextPred);
-    if (NB.hasGeneratedNodes()) {
-      Frontier.erase(NBPred);
-      Frontier.insert(NB.Frontier);
-    }
+  void takeNodes(const ExplodedNodeSet &S) {
+    for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
+      Frontier.erase(*I);
   }
+
+  void takeNodes(ExplodedNode *N) {
+    Frontier.erase(N);
+  }
+
+  void addNodes(const ExplodedNodeSet &S) {
+    Frontier.insert(S);
+  }
+
+  void addNodes(ExplodedNode *N) {
+    Frontier.Add(N);
+  }
+
 };
 
 class BranchNodeBuilder: public NodeBuilder {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp Mon Oct 24 13:25:58 2011
@@ -16,10 +16,4 @@
 using namespace clang;
 using namespace ento;
 
-CheckerContext::~CheckerContext() {
-  // Copy the results into the Dst set.
-  for (NodeBuilder::iterator I = NB.begin(),
-                             E = NB.end(); I != E; ++I) {
-    Dst.Add(*I);
-  }
-}
+CheckerContext::~CheckerContext() {}

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Mon Oct 24 13:25:58 2011
@@ -93,6 +93,9 @@
 static void expandGraphWithCheckers(CHECK_CTX checkCtx,
                                     ExplodedNodeSet &Dst,
                                     const ExplodedNodeSet &Src) {
+  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
+  if (Src.empty())
+    return;
 
   typename CHECK_CTX::CheckersTy::const_iterator
       I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
@@ -113,9 +116,18 @@
       CurrSet->clear();
     }
 
+    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
+    checkCtx.Eng.getBuilder().takeNodes(*PrevSet);
     for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
-         NI != NE; ++NI)
-      checkCtx.runChecker(*I, *CurrSet, *NI);
+         NI != NE; ++NI) {
+      checkCtx.runChecker(*I, B, *NI);
+    }
+
+    // If all the produced transitions are sinks, stop.
+    if (CurrSet->empty())
+      return;
+
+    checkCtx.Eng.getBuilder().addNodes(*CurrSet);
 
     // Update which NodeSet is the current one.
     PrevSet = CurrSet;
@@ -138,13 +150,13 @@
       : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckStmtFunc checkFn,
-                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
       // FIXME: Remove respondsToCallback from CheckerContext;
       ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
                                            ProgramPoint::PostStmtKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                 Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
 
       checkFn(S, C);
     }
@@ -178,12 +190,12 @@
       : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
-                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
       ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
                                            ProgramPoint::PostStmtKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
                                 K, Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
 
       checkFn(Msg, C);
     }
@@ -220,12 +232,12 @@
       : Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckLocationFunc checkFn,
-                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
       ProgramPoint::Kind K =  IsLoad ? ProgramPoint::PreLoadKind :
                                        ProgramPoint::PreStoreKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                 Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
 
       checkFn(Loc, IsLoad, S, C);
     }
@@ -258,11 +270,11 @@
       : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckBindFunc checkFn,
-                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
       ProgramPoint::Kind K =  ProgramPoint::PreStmtKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                 Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
 
       checkFn(Loc, Val, S, C);
     }
@@ -329,11 +341,11 @@
       : Checkers(checkers), SR(sr), S(s), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn,
-                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
       ProgramPoint::Kind K = ProgramPoint::PostPurgeDeadSymbolsKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                 Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
 
       checkFn(SR, C);
     }
@@ -438,11 +450,13 @@
     }
 #endif
 
+    Eng.getBuilder().takeNodes(Pred);
+    ExplodedNodeSet checkDst;
+    NodeBuilder B(Pred, checkDst, Eng.getBuilderContext());
     // Next, check if any of the EvalCall callbacks can evaluate the call.
     for (std::vector<EvalCallFunc>::iterator
            EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
          EI != EE; ++EI) {
-      ExplodedNodeSet checkDst;
       ProgramPoint::Kind K = ProgramPoint::PostStmtKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K,
                                 Pred->getLocationContext(), EI->Checker);
@@ -450,7 +464,7 @@
       { // CheckerContext generates transitions(populates checkDest) on
         // destruction, so introduce the scope to make sure it gets properly
         // populated.
-        CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, L, 0);
+        CheckerContext C(B, Eng, Pred, L, 0);
         evaluated = (*EI)(CE, C);
       }
       assert(!(evaluated && anyEvaluated)
@@ -458,6 +472,7 @@
       if (evaluated) {
         anyEvaluated = true;
         Dst.insert(checkDst);
+        Eng.getBuilder().addNodes(checkDst);
 #ifdef NDEBUG
         break; // on release don't check that no other checker also evals.
 #endif
@@ -466,6 +481,7 @@
     
     // If none of the checkers evaluated the call, ask ExprEngine to handle it.
     if (!anyEvaluated) {
+      Eng.getBuilder().addNodes(Pred);
       if (defaultEval)
         defaultEval->expandGraph(Dst, Pred);
       else

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Oct 24 13:25:58 2011
@@ -504,7 +504,7 @@
   if (MarkAsSink)
     N->markAsSink();
     
-  if (IsNew)
+  if (IsNew && !MarkAsSink)
     Frontier.Add(N);
 
   return (IsNew ? N : 0);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Oct 24 13:25:58 2011
@@ -964,6 +964,9 @@
   NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx);
   getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
                                                     Pred, *this);
+  // We generated only sinks.
+  if (TmpCheckersOut.empty())
+    return;
 
   BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF);
   for (NodeBuilder::iterator I = CheckerBldr.begin(),





More information about the cfe-commits mailing list