diff options
-rw-r--r-- | clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h | 21 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 3 |
2 files changed, 16 insertions, 8 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index cf4164dcd21..bf460df278a 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -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(); } diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 7d7b88a8118..d76710004c8 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -292,7 +292,8 @@ int64_t ExplodedNode::getID(ExplodedGraph *G) const { 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, |