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

Anna Zaks ganna at apple.com
Tue Nov 1 15:41:19 PDT 2011


Author: zaks
Date: Tue Nov  1 17:41:19 2011
New Revision: 143517

URL: http://llvm.org/viewvc/llvm-project?rev=143517&view=rev
Log:
[analyzer] Make sink attribute part of the node profile.

This prevents caching out on nodes with different sink flag.
(This is a cleaner fix for radar://10376675).

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=143517&r1=143516&r2=143517&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Tue Nov  1 17:41:19 2011
@@ -116,9 +116,12 @@
 
 public:
 
-  explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state)
+  explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state,
+                        bool IsSink)
     : Location(loc), State(state) {
     const_cast<ProgramState*>(State)->incrementReferenceCount();
+    if (IsSink)
+      Succs.setFlag();
   }
   
   ~ExplodedNode() {
@@ -149,13 +152,16 @@
   const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
-                      const ProgramPoint &Loc, const ProgramState *state) {
+                      const ProgramPoint &Loc,
+                      const ProgramState *state,
+                      bool IsSink) {
     ID.Add(Loc);
     ID.AddPointer(state);
+    ID.AddBoolean(IsSink);
   }
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
-    Profile(ID, getLocation(), getState());
+    Profile(ID, getLocation(), getState(), isSink());
   }
 
   /// addPredeccessor - Adds a predecessor to the current node, and
@@ -168,7 +174,6 @@
   bool pred_empty() const { return Preds.empty(); }
 
   bool isSink() const { return Succs.getFlag(); }
-  void markAsSink() { Succs.setFlag(); }
 
   ExplodedNode *getFirstPred() {
     return pred_empty() ? NULL : *(pred_begin());
@@ -271,12 +276,13 @@
   bool reclaimNodes;
 
 public:
-  /// getNode - Retrieve the node associated with a (Location,State) pair,
+
+  /// \brief Retrieve the node associated with a (Location,State) pair,
   ///  where the 'Location' is a ProgramPoint in the CFG.  If no node for
-  ///  this pair exists, it is created.  IsNew is set to true if
+  ///  this pair exists, it is created. IsNew is set to true if
   ///  the node was freshly created.
-
   ExplodedNode *getNode(const ProgramPoint &L, const ProgramState *State,
+                        bool IsSink = false,
                         bool* IsNew = 0);
 
   ExplodedGraph* MakeEmptyGraph() const {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=143517&r1=143516&r2=143517&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Nov  1 17:41:19 2011
@@ -441,7 +441,7 @@
                               ExplodedNode *Pred) {
 
   bool IsNew;
-  ExplodedNode *Node = G->getNode(Loc, State, &IsNew);
+  ExplodedNode *Node = G->getNode(Loc, State, false, &IsNew);
 
   if (Pred)
     Node->addPredecessor(Pred, *G);  // Link 'Node' with its predecessor.
@@ -485,7 +485,7 @@
   }
 
   bool IsNew;
-  ExplodedNode *Succ = G->getNode(Loc, N->getState(), &IsNew);
+  ExplodedNode *Succ = G->getNode(Loc, N->getState(), false, &IsNew);
   Succ->addPredecessor(N, *G);
 
   if (IsNew)
@@ -502,7 +502,7 @@
   CallExit Loc(CE, LocCtx);
 
   bool isNew;
-  ExplodedNode *Node = G->getNode(Loc, N->getState(), &isNew);
+  ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew);
   Node->addPredecessor(N, *G);
   return isNew ? Node : 0;
 }
@@ -543,17 +543,14 @@
                                             bool MarkAsSink) {
   HasGeneratedNodes = true;
   bool IsNew;
-  ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
+  ExplodedNode *N = C.Eng.G->getNode(Loc, State, MarkAsSink, &IsNew);
   N->addPredecessor(FromN, *C.Eng.G);
   Frontier.erase(FromN);
-  assert(IsNew || N->isSink() == MarkAsSink);
 
   if (!IsNew)
     return 0;
 
-  if (MarkAsSink)
-    N->markAsSink();
-  else
+  if (!MarkAsSink)
     Frontier.Add(N);
 
   return N;
@@ -582,25 +579,20 @@
 ExplodedNode*
 IndirectGotoNodeBuilder::generateNode(const iterator &I,
                                       const ProgramState *St,
-                                      bool isSink) {
+                                      bool IsSink) {
   bool IsNew;
-
   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
-                                      Pred->getLocationContext()), St, &IsNew);
-
+                                      Pred->getLocationContext()), St,
+                                      IsSink, &IsNew);
   Succ->addPredecessor(Pred, *Eng.G);
 
-  if (IsNew) {
-
-    if (isSink)
-      Succ->markAsSink();
-    else
-      Eng.WList->enqueue(Succ);
+  if (!IsNew)
+    return 0;
 
-    return Succ;
-  }
+  if (!IsSink)
+    Eng.WList->enqueue(Succ);
 
-  return NULL;
+  return Succ;
 }
 
 
@@ -610,20 +602,20 @@
 
   bool IsNew;
   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
-                                      Pred->getLocationContext()),
-                                      St, &IsNew);
+                                      Pred->getLocationContext()), St,
+                                      false, &IsNew);
   Succ->addPredecessor(Pred, *Eng.G);
-  if (IsNew) {
-    Eng.WList->enqueue(Succ);
-    return Succ;
-  }
-  return NULL;
+  if (!IsNew)
+    return 0;
+
+  Eng.WList->enqueue(Succ);
+  return Succ;
 }
 
 
 ExplodedNode*
 SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St,
-                                           bool isSink) {
+                                           bool IsSink) {
   // Get the block for the default case.
   assert(Src->succ_rbegin() != Src->succ_rend());
   CFGBlock *DefaultBlock = *Src->succ_rbegin();
@@ -634,21 +626,18 @@
     return NULL;
   
   bool IsNew;
-
   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
-                                      Pred->getLocationContext()), St, &IsNew);
+                                      Pred->getLocationContext()), St,
+                                      IsSink, &IsNew);
   Succ->addPredecessor(Pred, *Eng.G);
 
-  if (IsNew) {
-    if (isSink)
-      Succ->markAsSink();
-    else
-      Eng.WList->enqueue(Succ);
+  if (!IsNew)
+    return 0;
 
-    return Succ;
-  }
+  if (!IsSink)
+    Eng.WList->enqueue(Succ);
 
-  return NULL;
+  return Succ;
 }
 
 void CallEnterNodeBuilder::generateNode(const ProgramState *state) {
@@ -706,7 +695,7 @@
   BlockEdge Loc(Entry, SuccB, CalleeCtx);
 
   bool isNew;
-  ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
+  ExplodedNode *Node = Eng.G->getNode(Loc, state, false, &isNew);
   Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
 
   if (isNew)
@@ -721,7 +710,7 @@
   // that triggers the dtor.
   PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
   bool isNew;
-  ExplodedNode *Node = Eng.G->getNode(Loc, state, &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(),

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp?rev=143517&r1=143516&r2=143517&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp Tue Nov  1 17:41:19 2011
@@ -215,12 +215,14 @@
 }
 
 ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
-                                     const ProgramState *State, bool* IsNew) {
+                                     const ProgramState *State,
+                                     bool IsSink,
+                                     bool* IsNew) {
   // Profile 'State' to determine if we already have an existing node.
   llvm::FoldingSetNodeID profile;
   void *InsertPos = 0;
 
-  NodeTy::Profile(profile, L, State);
+  NodeTy::Profile(profile, L, State, IsSink);
   NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
 
   if (!V) {
@@ -234,7 +236,7 @@
       V = (NodeTy*) getAllocator().Allocate<NodeTy>();
     }
 
-    new (V) NodeTy(L, State);
+    new (V) NodeTy(L, State, IsSink);
 
     if (reclaimNodes) {
       if (!recentlyAllocatedNodes)
@@ -334,7 +336,7 @@
 
     // Create the corresponding node in the new graph and record the mapping
     // from the old node to the new node.
-    ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, NULL);
+    ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, N->isSink(), 0);
     Pass2[N] = NewN;
 
     // Also record the reverse mapping from the new node to the old node.
@@ -372,10 +374,6 @@
       if (Pass1.count(*I))
         WL2.push_back(*I);
     }
-
-    // Finally, explicitly mark all nodes without any successors as sinks.
-    if (N->isSink())
-      NewN->markAsSink();
   }
 
   return G;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=143517&r1=143516&r2=143517&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Nov  1 17:41:19 2011
@@ -1595,7 +1595,7 @@
 }
 
 void ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
-                                     const Expr *Ex) {
+                                   const Expr *Ex) {
   StmtNodeBuilder Bldr(Src, Dst, *currentBuilderContext);
   
   for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {





More information about the cfe-commits mailing list