aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-10-17 23:10:09 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-10-17 23:10:09 +0000
commitd0e3ed0b01ba7e55081e5b2593460b7b1486fd24 (patch)
tree38ef8ff2978259425fb6fc6a9cf218778cd7c4a0 /lib
parent40a1cfa0b13160d82f688daa7fbab9f249679617 (diff)
[analyzer] Assign truly stable identifiers to exploded nodes.
ExplodedGraph nodes will now have a numeric identifier stored in them which will keep track of the order in which the nodes were created and it will be fully deterministic both accross runs and across machines. This is extremely useful for debugging as it allows reliably setting conditional breakpoints by node IDs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp14
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp18
3 files changed, 14 insertions, 21 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index f689d8e76a..1864bcef9b 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -2566,7 +2566,8 @@ BugPathInfo *BugPathGetter::getNextBugPath() {
// Create the equivalent node in the new graph with the same state
// and location.
ExplodedNode *NewN = GNew->createUncachedNode(
- OrigN->getLocation(), OrigN->getState(), OrigN->isSink());
+ OrigN->getLocation(), OrigN->getState(),
+ OrigN->getID(), OrigN->isSink());
// Link up the new node with the previous node.
if (Succ)
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index a8fa7ad2d9..c483849227 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -283,10 +283,6 @@ ExplodedNode * const *ExplodedNode::NodeGroup::end() const {
return Storage.getAddrOfPtr1() + 1;
}
-int64_t ExplodedNode::getID(ExplodedGraph *G) const {
- return G->getAllocator().identifyKnownAlignedObject<ExplodedNode>(this);
-}
-
bool ExplodedNode::isTrivial() const {
return pred_size() == 1 && succ_size() == 1 &&
getFirstPred()->getState()->getID() == getState()->getID() &&
@@ -417,14 +413,14 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
V = (NodeTy*) getAllocator().Allocate<NodeTy>();
}
- new (V) NodeTy(L, State, IsSink);
+ ++NumNodes;
+ new (V) NodeTy(L, State, NumNodes, IsSink);
if (ReclaimNodeInterval)
ChangedNodes.push_back(V);
// Insert the node into the node set and return it.
Nodes.InsertNode(V, InsertPos);
- ++NumNodes;
if (IsNew) *IsNew = true;
}
@@ -436,9 +432,10 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
ExplodedNode *ExplodedGraph::createUncachedNode(const ProgramPoint &L,
ProgramStateRef State,
+ int64_t Id,
bool IsSink) {
NodeTy *V = (NodeTy *) getAllocator().Allocate<NodeTy>();
- new (V) NodeTy(L, State, IsSink);
+ new (V) NodeTy(L, State, Id, IsSink);
return V;
}
@@ -498,7 +495,8 @@ ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks,
// Create the corresponding node in the new graph and record the mapping
// from the old node to the new node.
- ExplodedNode *NewN = G->createUncachedNode(N->getLocation(), N->State, N->isSink());
+ ExplodedNode *NewN = G->createUncachedNode(N->getLocation(), N->State,
+ N->getID(), N->isSink());
Pass2[N] = NewN;
// Also record the reverse mapping from the new node to the old node.
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 8629fd98db..ea1df1b0df 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -3061,16 +3061,7 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
const unsigned int Space = 1;
ProgramStateRef State = N->getState();
- auto Noop = [](const ExplodedNode*){};
- bool HasReport = traverseHiddenNodes(
- N, Noop, Noop, &nodeHasBugReport);
- bool IsSink = traverseHiddenNodes(
- N, Noop, Noop, [](const ExplodedNode *N) { return N->isSink(); });
-
- Out << "{ \"node_id\": " << N->getID(G) << ", \"pointer\": \""
- << (const void *)N << "\", \"state_id\": " << State->getID()
- << ", \"has_report\": " << (HasReport ? "true" : "false")
- << ", \"is_sink\": " << (IsSink ? "true" : "false")
+ Out << "{ \"state_id\": " << State->getID()
<< ",\\l";
Indent(Out, Space, IsDot) << "\"program_points\": [\\l";
@@ -3083,9 +3074,12 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
OtherNode->getLocation().printJson(Out, /*NL=*/"\\l");
Out << ", \"tag\": ";
if (const ProgramPointTag *Tag = OtherNode->getLocation().getTag())
- Out << '\"' << Tag->getTagDescription() << "\" }";
+ Out << '\"' << Tag->getTagDescription() << "\"";
else
- Out << "null }";
+ Out << "null";
+ Out << ", \"node_id\": " << OtherNode->getID() <<
+ ", \"is_sink\": " << OtherNode->isSink() <<
+ ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }";
},
// Adds a comma and a new-line between each program point.
[&](const ExplodedNode *) { Out << ",\\l"; },