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