r345341 - [analyzer] Fix a bug in "collapsed" graph viewer

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 25 16:38:58 PDT 2018


Author: george.karpenkov
Date: Thu Oct 25 16:38:58 2018
New Revision: 345341

URL: http://llvm.org/viewvc/llvm-project?rev=345341&view=rev
Log:
[analyzer] Fix a bug in "collapsed" graph viewer

Nodes which have only one predecessor and only one successor can not
always be hidden, even if all states are the same.
An additional condition is needed: the predecessor may have only one successor.
This can be seen on this example:

```
  A
 / \
B   C
 \ /
  D
```

Nodes B and C can not be hidden even if all nodes in the graph have the
same state.

Differential Revision: https://reviews.llvm.org/D53735

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
    cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.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=345341&r1=345340&r2=345341&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Thu Oct 25 16:38:58 2018
@@ -210,10 +210,14 @@ public:
     return const_cast<ExplodedNode*>(this)->getFirstPred();
   }
 
-  const ExplodedNode *getFirstSucc() const {
+  ExplodedNode *getFirstSucc() {
     return succ_empty() ? nullptr : *(succ_begin());
   }
 
+  const ExplodedNode *getFirstSucc() const {
+    return const_cast<ExplodedNode*>(this)->getFirstSucc();
+  }
+
   // Iterators over successor and predecessor vertices.
   using succ_iterator = ExplodedNode * const *;
   using const_succ_iterator = const ExplodedNode * const *;
@@ -243,8 +247,10 @@ public:
   int64_t getID(ExplodedGraph *G) const;
 
   /// The node is trivial if it has only one successor, only one predecessor,
+  /// it's predecessor has only one successor,
   /// and its program state is the same as the program state of the previous
   /// node.
+  /// Trivial nodes may be skipped while printing exploded graph.
   bool isTrivial() const;
 
 private:
@@ -460,7 +466,6 @@ public:
 // GraphTraits
 
 namespace llvm {
-
   template <> struct GraphTraits<clang::ento::ExplodedGraph *> {
     using GraphTy = clang::ento::ExplodedGraph *;
     using NodeRef = clang::ento::ExplodedNode *;
@@ -471,17 +476,19 @@ namespace llvm {
       return *G->roots_begin();
     }
 
+    static bool predecessorOfTrivial(NodeRef N) {
+      return N->succ_size() == 1 && N->getFirstSucc()->isTrivial();
+    }
+
     static ChildIteratorType child_begin(NodeRef N) {
-      if (N->succ_size() == 1 && (*N->succ_begin())->isTrivial()) {
+      if (predecessorOfTrivial(N))
         return child_begin(*N->succ_begin());
-      }
       return N->succ_begin();
     }
 
     static ChildIteratorType child_end(NodeRef N) {
-      if (N->succ_size() == 1 && (*N->succ_begin())->isTrivial()) {
-        return child_end(*N->succ_begin());
-      }
+      if (predecessorOfTrivial(N))
+        return child_end(N->getFirstSucc());
       return N->succ_end();
     }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp?rev=345341&r1=345340&r2=345341&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp Thu Oct 25 16:38:58 2018
@@ -292,7 +292,8 @@ int64_t ExplodedNode::getID(ExplodedGrap
 
 bool ExplodedNode::isTrivial() const {
   return pred_size() == 1 && succ_size() == 1 &&
-         (*pred_begin())->getState()->getID() == getState()->getID();
+         getFirstPred()->getState()->getID() == getState()->getID() &&
+         getFirstPred()->succ_size() == 1;
 }
 
 ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,




More information about the cfe-commits mailing list