[analyzer] Remove CallExitNodeBuilder, and have ExprEngine::processCallExit() do...
authorTed Kremenek <kremenek@apple.com>
Sat, 7 Jan 2012 00:00:59 +0000 (00:00 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 7 Jan 2012 00:00:59 +0000 (00:00 +0000)
Along the way, fix Exprengine::processCallExit() to also perform the postStmt callback for checkers for CallExprs.

llvm-svn: 147697

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

index 875df3a..af5ed27 100644 (file)
@@ -47,7 +47,6 @@ class CoreEngine {
   friend class SwitchNodeBuilder;
   friend class EndOfFunctionNodeBuilder;
   friend class CallEnterNodeBuilder;
-  friend class CallExitNodeBuilder;
 
 public:
   typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
@@ -570,21 +569,6 @@ public:
   void generateNode(const ProgramState *state);
 };
 
-class CallExitNodeBuilder {
-  CoreEngine &Eng;
-  const ExplodedNode *Pred;
-
-public:
-  CallExitNodeBuilder(CoreEngine &eng, const ExplodedNode *pred)
-    : Eng(eng), Pred(pred) {}
-
-  const ExplodedNode *getPredecessor() const { return Pred; }
-
-  const ProgramState *getState() const { return Pred->getState(); }
-
-  void generateNode(const ProgramState *state);
-}; 
-
 } // end GR namespace
 
 } // end clang namespace
index f6d4998..47178b5 100644 (file)
@@ -188,7 +188,7 @@ public:
   void processCallEnter(CallEnterNodeBuilder &builder);
 
   /// Generate the first post callsite node.
-  void processCallExit(CallExitNodeBuilder &builder);
+  void processCallExit(ExplodedNode *Pred);
 
   /// Called by CoreEngine when the analysis worklist has terminated.
   void processEndWorklist(bool hasWorkRemaining);
index f2fa8fc..7008ba3 100644 (file)
@@ -38,7 +38,6 @@ class IndirectGotoNodeBuilder;
 class SwitchNodeBuilder;
 class EndOfFunctionNodeBuilder;
 class CallEnterNodeBuilder;
-class CallExitNodeBuilder;
 class NodeBuilderWithSinks;
 class MemRegion;
 
@@ -88,7 +87,7 @@ public:
   virtual void processCallEnter(CallEnterNodeBuilder &builder) = 0;
 
   // Generate the first post callsite node.
-  virtual void processCallExit(CallExitNodeBuilder &builder) = 0;
+  virtual void processCallExit(ExplodedNode *Pred) = 0;
 
   /// Called by ConstraintManager. Used to call checker-specific
   /// logic for handling assumptions on symbolic values.
index bf4bf2d..c505c44 100644 (file)
@@ -254,8 +254,7 @@ void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
 }
 
 void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
-  CallExitNodeBuilder Builder(*this, Pred);
-  SubEng.processCallExit(Builder);
+  SubEng.processCallExit(Pred);
 }
 
 void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
@@ -707,18 +706,3 @@ void CallEnterNodeBuilder::generateNode(const ProgramState *state) {
   if (isNew)
     Eng.WList->enqueue(Node);
 }
-
-void CallExitNodeBuilder::generateNode(const ProgramState *state) {
-  // Get the callee's location context.
-  const StackFrameContext *LocCtx 
-                         = cast<StackFrameContext>(Pred->getLocationContext());
-  // When exiting an implicit automatic obj dtor call, the callsite is the Stmt
-  // that triggers the dtor.
-  PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
-  bool isNew;
-  ExplodedNode *Node = Eng.G->getNode(Loc, state, false, &isNew);
-  Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
-  if (isNew)
-    Eng.WList->enqueue(Node, LocCtx->getCallSiteBlock(),
-                       LocCtx->getIndex() + 1);
-}
index 3b508d2..8e9cc3c 100644 (file)
@@ -34,11 +34,10 @@ void ExprEngine::processCallEnter(CallEnterNodeBuilder &B) {
   B.generateNode(state);
 }
 
-void ExprEngine::processCallExit(CallExitNodeBuilder &B) {
-  const ProgramState *state = B.getState();
-  const ExplodedNode *Pred = B.getPredecessor();
+void ExprEngine::processCallExit(ExplodedNode *Pred) {
+  const ProgramState *state = Pred->getState();
   const StackFrameContext *calleeCtx = 
-    cast<StackFrameContext>(Pred->getLocationContext());
+    Pred->getLocationContext()->getCurrentStackFrame();
   const Stmt *CE = calleeCtx->getCallSite();
   
   // If the callee returns an expression, bind its value to CallExpr.
@@ -60,8 +59,21 @@ void ExprEngine::processCallExit(CallExitNodeBuilder &B) {
     // Always bind the region to the CXXConstructExpr.
     state = state->BindExpr(CCE, Pred->getLocationContext(), ThisV);
   }
+
   
-  B.generateNode(state);
+  PostStmt Loc(CE, calleeCtx->getParent());
+  bool isNew;
+  ExplodedNode *N = G.getNode(Loc, state, false, &isNew);
+  N->addPredecessor(Pred, G);
+  if (!isNew)
+    return;
+  
+  // Perform the post-condition check of the CallExpr.
+  ExplodedNodeSet Dst;
+  getCheckerManager().runCheckersForPostStmt(Dst, N, CE, *this);
+  
+  // Enqueue nodes in Dst on the worklist.
+  Engine.enqueue(Dst);
 }
 
 static bool isPointerToConst(const ParmVarDecl *ParamDecl) {