[cfe-commits] r142943 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/

Anna Zaks ganna at apple.com
Tue Oct 25 12:56:49 PDT 2011


Author: zaks
Date: Tue Oct 25 14:56:48 2011
New Revision: 142943

URL: http://llvm.org/viewvc/llvm-project?rev=142943&view=rev
Log:
[analyze] Convert EndOfPath callback to use CheckerContext

Get rid of the EndOfPathBuilder completely.
Use the generic NodeBuilder to generate nodes.
Enqueue the end of path frontier explicitly.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.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/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Tue Oct 25 14:56:48 2011
@@ -199,9 +199,9 @@
 
 class EndPath {
   template <typename CHECKER>
-  static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
-                            ExprEngine &Eng) {
-    ((const CHECKER *)checker)->checkEndPath(B, Eng);
+  static void _checkEndPath(void *checker,
+                            CheckerContext &C) {
+    ((const CHECKER *)checker)->checkEndPath(C);
   }
 
 public:

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Tue Oct 25 14:56:48 2011
@@ -39,8 +39,8 @@
   class ExplodedNodeSet;
   class ExplodedGraph;
   class ProgramState;
-  class EndOfFunctionNodeBuilder;
   class NodeBuilder;
+  struct NodeBuilderContext;
   class MemRegion;
   class SymbolReaper;
 
@@ -230,7 +230,9 @@
                                  ExprEngine &Eng);
 
   /// \brief Run checkers for end of path.
-  void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
+  void runCheckersForEndPath(NodeBuilderContext &BC,
+                             ExplodedNodeSet &Dst,
+                             ExprEngine &Eng);
 
   /// \brief Run checkers for branch condition.
   void runCheckersForBranchCondition(const Stmt *condition,
@@ -334,7 +336,7 @@
   typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
       CheckEndAnalysisFunc;
   
-  typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
+  typedef CheckerFn<void (CheckerContext &)>
       CheckEndPathFunc;
   
   typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExplodedNode *Pred,

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=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Tue Oct 25 14:56:48 2011
@@ -171,9 +171,9 @@
 struct NodeBuilderContext {
   CoreEngine &Eng;
   const CFGBlock *Block;
-  ExplodedNode *ContextPred;
+  ExplodedNode *Pred;
   NodeBuilderContext(CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
-    : Eng(E), Block(B), ContextPred(N) { assert(B); assert(!N->isSink()); }
+    : Eng(E), Block(B), Pred(N) { assert(B); assert(!N->isSink()); }
 
   /// \brief Return the CFGBlock associated with this builder.
   const CFGBlock *getBlock() const { return Block; }
@@ -182,10 +182,9 @@
   /// visited on the exploded graph path.
   unsigned getCurrentBlockCount() const {
     return Eng.WList->getBlockCounter().getNumVisited(
-                    ContextPred->getLocationContext()->getCurrentStackFrame(),
+                    Pred->getLocationContext()->getCurrentStackFrame(),
                     Block->getBlockID());
   }
-
 };
 
 /// \class NodeBuilder
@@ -289,15 +288,6 @@
   void addNodes(ExplodedNode *N) { Frontier.Add(N); }
 };
 
-class CommonNodeBuilder {
-protected:
-  ExplodedNode *Pred;
-  CoreEngine &Eng;
-
-  CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {}
-  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter(); }
-};
-
 /// \class StmtNodeBuilder
 /// \brief This builder class is useful for generating nodes that resulted from
 /// visiting a statement. The main difference from it's parent NodeBuilder is
@@ -523,47 +513,6 @@
   const PP_T &getProgramPoint() const { return cast<PP_T>(pp); }
 };
 
-class EndOfFunctionNodeBuilder : public CommonNodeBuilder {
-  const CFGBlock &B;
-  const ProgramPointTag *Tag;
-
-public:
-  bool hasGeneratedNode;
-
-public:
-  EndOfFunctionNodeBuilder(const CFGBlock *b, ExplodedNode *N, CoreEngine* e,
-                           const ProgramPointTag *tag = 0)
-    : CommonNodeBuilder(e, N), B(*b), Tag(tag), hasGeneratedNode(false) {}
-
-  ~EndOfFunctionNodeBuilder();
-
-  EndOfFunctionNodeBuilder withCheckerTag(const ProgramPointTag *tag) {
-    return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag);
-  }
-
-  WorkList &getWorkList() { return *Eng.WList; }
-
-  ExplodedNode *getPredecessor() const { return Pred; }
-
-  unsigned getCurrentBlockCount() const {
-    return getBlockCounter().getNumVisited(
-                            Pred->getLocationContext()->getCurrentStackFrame(),
-                                           B.getBlockID());
-  }
-
-  ExplodedNode *generateNode(const ProgramState *State,
-                             ExplodedNode *P = 0,
-                             const ProgramPointTag *tag = 0);
-
-  void GenerateCallExitNode(const ProgramState *state);
-
-  const CFGBlock *getBlock() const { return &B; }
-
-  const ProgramState *getState() const {
-    return getPredecessor()->getState();
-  }
-};
-
 class CallEnterNodeBuilder {
   CoreEngine &Eng;
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Oct 25 14:56:48 2011
@@ -124,6 +124,8 @@
   const Stmt *getStmt() const;
 
   void GenerateAutoTransition(ExplodedNode *N);
+  void enqueueEndOfPath(ExplodedNodeSet &S);
+  void GenerateCallExitNode(ExplodedNode *N);
 
   /// ViewGraph - Visualize the ExplodedGraph created by executing the
   ///  simulation.
@@ -181,7 +183,7 @@
 
   /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
   ///  nodes when the control reaches the end of a function.
-  void processEndOfFunction(EndOfFunctionNodeBuilder& builder);
+  void processEndOfFunction(NodeBuilderContext& BC);
 
   /// Generate the entry node of the callee.
   void processCallEnter(CallEnterNodeBuilder &builder);

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Tue Oct 25 14:56:48 2011
@@ -82,7 +82,7 @@
 
   /// Called by CoreEngine.  Used to generate end-of-path
   /// nodes when the control reaches the end of a function.
-  virtual void processEndOfFunction(EndOfFunctionNodeBuilder& builder) = 0;
+  virtual void processEndOfFunction(NodeBuilderContext& BC) = 0;
 
   // Generate the entry node of the callee.
   virtual void processCallEnter(CallEnterNodeBuilder &builder) = 0;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp Tue Oct 25 14:56:48 2011
@@ -58,7 +58,7 @@
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *S, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
-  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
+  void checkEndPath(CheckerContext &Ctx) const;
 
 private:
   typedef std::pair<SymbolRef, const AllocationState*> AllocationPair;
@@ -557,9 +557,8 @@
 }
 
 // TODO: Remove this after we ensure that checkDeadSymbols are always called.
-void MacOSKeychainAPIChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
-                                           ExprEngine &Eng) const {
-  const ProgramState *state = B.getState();
+void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const {
+  const ProgramState *state = Ctx.getState();
   AllocatedSetTy AS = state->get<AllocatedData>();
   if (AS.isEmpty())
     return;
@@ -575,7 +574,7 @@
     // allocation, do not report.
     if (state->getSymVal(I.getKey()) ||
         definitelyReturnedError(I->second.Region, state,
-                                Eng.getSValBuilder())) {
+                                Ctx.getSValBuilder())) {
       continue;
     }
     Errors.push_back(std::make_pair(I->first, &I->second));
@@ -585,15 +584,14 @@
   if (!Changed)
     return;
 
-  ExplodedNode *N = B.generateNode(state);
+  ExplodedNode *N = Ctx.generateNode(state);
   if (!N)
     return;
 
   // Generate the error reports.
   for (AllocationPairVec::iterator I = Errors.begin(), E = Errors.end();
                                                        I != E; ++I) {
-    Eng.getBugReporter().EmitReport(
-      generateAllocatedDataNotReleasedReport(*I, N));
+    Ctx.EmitReport(generateAllocatedDataNotReleasedReport(*I, N));
   }
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Oct 25 14:56:48 2011
@@ -78,7 +78,7 @@
 
   bool evalCall(const CallExpr *CE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
-  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
+  void checkEndPath(CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
   const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
                             bool Assumption) const;
@@ -604,21 +604,20 @@
   }
 }
 
-void MallocChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
-                                 ExprEngine &Eng) const {
-  const ProgramState *state = B.getState();
+void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
+  const ProgramState *state = Ctx.getState();
   RegionStateTy M = state->get<RegionState>();
 
   for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
     RefState RS = I->second;
     if (RS.isAllocated()) {
-      ExplodedNode *N = B.generateNode(state);
+      ExplodedNode *N = Ctx.generateNode(state);
       if (N) {
         if (!BT_Leak)
           BT_Leak.reset(new BuiltinBug("Memory leak",
                     "Allocated memory never released. Potential memory leak."));
         BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
-        Eng.getBugReporter().EmitReport(R);
+        Ctx.EmitReport(R);
       }
     }
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Oct 25 14:56:48 2011
@@ -47,24 +47,13 @@
   EndOfFunctionNodeBuilder *ENB;
 public:
   GenericNodeBuilderRefCount(CheckerContext &c,
-                             const ProgramPointTag *t)
+                             const ProgramPointTag *t = 0)
   : C(&c), tag(t), ENB(0) {}
 
-  GenericNodeBuilderRefCount(EndOfFunctionNodeBuilder &enb)
-  : C(0), tag(0), ENB(&enb) {}
-
   ExplodedNode *MakeNode(const ProgramState *state, ExplodedNode *Pred,
                          bool MarkAsSink = false) {
-    if (C) {
-        return C->generateNode(state, Pred, tag, false, MarkAsSink);
-    }
-
-    assert(ENB);
-    ExplodedNode *N = ENB->generateNode(state, Pred);
-    if (MarkAsSink) 
-      N->markAsSink();
-    
-    return N;
+    assert(C);
+    return C->generateNode(state, Pred, tag, false, MarkAsSink);
   }
 };
 } // end anonymous namespace
@@ -2445,7 +2434,7 @@
                                 SymbolRef Sym, const ProgramState *state) const;
                                               
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
-  void checkEndPath(EndOfFunctionNodeBuilder &Builder, ExprEngine &Eng) const;
+  void checkEndPath(CheckerContext &C) const;
 
   const ProgramState *updateSymbol(const ProgramState *state, SymbolRef sym,
                                    RefVal V, ArgEffect E, RefVal::Kind &hasErr,
@@ -3439,12 +3428,12 @@
   return N;
 }
 
-void RetainCountChecker::checkEndPath(EndOfFunctionNodeBuilder &Builder,
-                                      ExprEngine &Eng) const {
-  const ProgramState *state = Builder.getState();
-  GenericNodeBuilderRefCount Bd(Builder);
+void RetainCountChecker::checkEndPath(CheckerContext &Ctx) const {
+  const ProgramState *state = Ctx.getState();
+  GenericNodeBuilderRefCount Bd(Ctx);
   RefBindings B = state->get<RefBindings>();
-  ExplodedNode *Pred = Builder.getPredecessor();
+  ExplodedNode *Pred = Ctx.getPredecessor();
+  ExprEngine &Eng = Ctx.getEngine();
 
   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
     llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, Eng,

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp Tue Oct 25 14:56:48 2011
@@ -31,7 +31,7 @@
 
 public:
   void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
-  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
+  void checkEndPath(CheckerContext &Ctx) const;
 private:
   void EmitStackError(CheckerContext &C, const MemRegion *R,
                       const Expr *RetE) const;
@@ -136,22 +136,22 @@
   }
 }
 
-void StackAddrEscapeChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
-                                        ExprEngine &Eng) const {
-
-  const ProgramState *state = B.getState();
+void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {
+  const ProgramState *state = Ctx.getState();
 
   // Iterate over all bindings to global variables and see if it contains
   // a memory region in the stack space.
   class CallBack : public StoreManager::BindingsHandler {
   private:
-    ExprEngine &Eng;
+    CheckerContext &Ctx;
     const StackFrameContext *CurSFC;
   public:
     SmallVector<std::pair<const MemRegion*, const MemRegion*>, 10> V;
 
-    CallBack(ExprEngine &Eng, const LocationContext *LCtx)
-      : Eng(Eng), CurSFC(LCtx->getCurrentStackFrame()) {}
+    CallBack(CheckerContext &CC) :
+      Ctx(CC),
+      CurSFC(CC.getPredecessor()->getLocationContext()->getCurrentStackFrame())
+    {}
     
     bool HandleBinding(StoreManager &SMgr, Store store,
                        const MemRegion *region, SVal val) {
@@ -165,7 +165,7 @@
         
       // Under automated retain release, it is okay to assign a block
       // directly to a global variable.
-      if (Eng.getContext().getLangOptions().ObjCAutoRefCount &&
+      if (Ctx.getASTContext().getLangOptions().ObjCAutoRefCount &&
           isa<BlockDataRegion>(vR))
         return true;
 
@@ -181,14 +181,14 @@
     }
   };
     
-  CallBack cb(Eng, B.getPredecessor()->getLocationContext());
+  CallBack cb(Ctx);
   state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);
 
   if (cb.V.empty())
     return;
 
   // Generate an error node.
-  ExplodedNode *N = B.generateNode(state);
+  ExplodedNode *N = Ctx.generateNode(state);
   if (!N)
     return;
 
@@ -204,7 +204,7 @@
     llvm::SmallString<512> buf;
     llvm::raw_svector_ostream os(buf);
     SourceRange range = GenName(os, cb.V[i].second,
-                                Eng.getContext().getSourceManager());
+                                Ctx.getSourceManager());
     os << " is still referred to by the global variable '";
     const VarRegion *VR = cast<VarRegion>(cb.V[i].first->getBaseRegion());
     os << *VR->getDecl()
@@ -213,7 +213,7 @@
     if (range.isValid())
       report->addRange(range);
 
-    Eng.getBugReporter().EmitReport(report);
+    Ctx.EmitReport(report);
   }
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Tue Oct 25 14:56:48 2011
@@ -75,7 +75,7 @@
 
   bool evalCall(const CallExpr *CE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
-  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
+  void checkEndPath(CheckerContext &Ctx) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
 
 private:
@@ -418,23 +418,22 @@
   }
 }
 
-void StreamChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
-                                 ExprEngine &Eng) const {
-  const ProgramState *state = B.getState();
+void StreamChecker::checkEndPath(CheckerContext &Ctx) const {
+  const ProgramState *state = Ctx.getState();
   typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
   SymMap M = state->get<StreamState>();
   
   for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
     StreamState SS = I->second;
     if (SS.isOpened()) {
-      ExplodedNode *N = B.generateNode(state);
+      ExplodedNode *N = Ctx.generateNode(state);
       if (N) {
         if (!BT_ResourceLeak)
           BT_ResourceLeak.reset(new BuiltinBug("Resource Leak", 
                          "Opened File never closed. Potential Resource leak."));
         BugReport *R = new BugReport(*BT_ResourceLeak, 
                                      BT_ResourceLeak->getDescription(), N);
-        Eng.getBugReporter().EmitReport(R);
+        Ctx.EmitReport(R);
       }
     }
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Tue Oct 25 14:56:48 2011
@@ -298,12 +298,25 @@
 }
 
 /// \brief Run checkers for end of path.
-void CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
+// Note, We do not chain the checker output (like in expandGraphWithCheckers)
+// for this callback since end of path nodes are expected to be final.
+void CheckerManager::runCheckersForEndPath(NodeBuilderContext &BC,
+                                           ExplodedNodeSet &Dst,
                                            ExprEngine &Eng) {
+  ExplodedNode *Pred = BC.Pred;
+  
+  // We define the builder outside of the loop bacause if at least one checkers
+  // creates a sucsessor for Pred, we do not need to generate an 
+  // autotransition for it.
+  NodeBuilder Bldr(Pred, Dst, BC);
   for (unsigned i = 0, e = EndPathCheckers.size(); i != e; ++i) {
-    CheckEndPathFunc fn = EndPathCheckers[i];
-    EndOfFunctionNodeBuilder specialB = B.withCheckerTag(fn.Checker);
-    fn(specialB, Eng);
+    CheckEndPathFunc checkFn = EndPathCheckers[i];
+
+    const ProgramPoint &L = BlockEntrance(BC.Block,
+                                          Pred->getLocationContext(),
+                                          checkFn.Checker);
+    CheckerContext C(Bldr, Eng, Pred, L, 0);
+    checkFn(C);
   }
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Oct 25 14:56:48 2011
@@ -269,8 +269,8 @@
             && "EXIT block cannot contain Stmts.");
 
     // Process the final state transition.
-    EndOfFunctionNodeBuilder Builder(Blk, Pred, this);
-    SubEng.processEndOfFunction(Builder);
+    NodeBuilderContext BuilderCtx(*this, Blk, Pred);
+    SubEng.processEndOfFunction(BuilderCtx);
 
     // This path is done. Don't enqueue any more nodes.
     return;
@@ -597,57 +597,6 @@
   return NULL;
 }
 
-EndOfFunctionNodeBuilder::~EndOfFunctionNodeBuilder() {
-  // Auto-generate an EOP node if one has not been generated.
-  if (!hasGeneratedNode) {
-    // If we are in an inlined call, generate CallExit node.
-    if (Pred->getLocationContext()->getParent())
-      GenerateCallExitNode(Pred->State);
-    else
-      generateNode(Pred->State);
-  }
-}
-
-ExplodedNode*
-EndOfFunctionNodeBuilder::generateNode(const ProgramState *State,
-                                       ExplodedNode *P,
-                                       const ProgramPointTag *tag) {
-  hasGeneratedNode = true;
-  bool IsNew;
-
-  ExplodedNode *Node = Eng.G->getNode(BlockEntrance(&B,
-                               Pred->getLocationContext(), tag ? tag : Tag),
-                               State, &IsNew);
-
-  Node->addPredecessor(P ? P : Pred, *Eng.G);
-
-  if (IsNew) {
-    Eng.G->addEndOfPath(Node);
-    return Node;
-  }
-
-  return NULL;
-}
-
-void EndOfFunctionNodeBuilder::GenerateCallExitNode(const ProgramState *state) {
-  hasGeneratedNode = true;
-  // Create a CallExit node and enqueue it.
-  const StackFrameContext *LocCtx
-                         = cast<StackFrameContext>(Pred->getLocationContext());
-  const Stmt *CE = LocCtx->getCallSite();
-
-  // Use the the callee location context.
-  CallExit Loc(CE, LocCtx);
-
-  bool isNew;
-  ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
-  Node->addPredecessor(Pred, *Eng.G);
-
-  if (isNew)
-    Eng.WList->enqueue(Node);
-}
-                                                
-
 void CallEnterNodeBuilder::generateNode(const ProgramState *state) {
   // Check if the callee is in the same translation unit.
   if (CalleeCtx->getTranslationUnit() != 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142943&r1=142942&r2=142943&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Oct 25 14:56:48 2011
@@ -1153,11 +1153,42 @@
     builder.generateNode(I, state);
 }
 
+// TODO: The next two functions should be moved into CoreEngine.
+void ExprEngine::GenerateCallExitNode(ExplodedNode *N) {
+  // Create a CallExit node and enqueue it.
+  const StackFrameContext *LocCtx
+                         = cast<StackFrameContext>(N->getLocationContext());
+  const Stmt *CE = LocCtx->getCallSite();
+
+  // Use the the callee location context.
+  CallExit Loc(CE, LocCtx);
+
+  bool isNew;
+  ExplodedNode *Node = Engine.G->getNode(Loc, N->getState(), &isNew);
+  Node->addPredecessor(N, *Engine.G);
+
+  if (isNew)
+    Engine.WList->enqueue(Node);
+}
+
+void ExprEngine::enqueueEndOfPath(ExplodedNodeSet &S) {
+  for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I) {
+    ExplodedNode *N = *I;
+    // If we are in an inlined call, generate CallExit node.
+    if (N->getLocationContext()->getParent())
+      GenerateCallExitNode(N);
+    else
+      Engine.G->addEndOfPath(N);
+  }
+}
+
 /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
 ///  nodes when the control reaches the end of a function.
-void ExprEngine::processEndOfFunction(EndOfFunctionNodeBuilder& builder) {
-  StateMgr.EndPath(builder.getState());
-  getCheckerManager().runCheckersForEndPath(builder, *this);
+void ExprEngine::processEndOfFunction(NodeBuilderContext& BC) {
+  StateMgr.EndPath(BC.Pred->getState());
+  ExplodedNodeSet Dst;
+  getCheckerManager().runCheckersForEndPath(BC, Dst, *this);
+  enqueueEndOfPath(Dst);
 }
 
 /// ProcessSwitch - Called by CoreEngine.  Used to generate successor





More information about the cfe-commits mailing list