aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h11
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp14
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp18
-rw-r--r--test/Analysis/dump_egraph.c4
-rw-r--r--test/Analysis/exploded-graph-rewriter/checker_messages.dot9
-rw-r--r--test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot44
-rw-r--r--test/Analysis/exploded-graph-rewriter/constraints.dot14
-rw-r--r--test/Analysis/exploded-graph-rewriter/constraints_diff.dot42
-rw-r--r--test/Analysis/exploded-graph-rewriter/edge.dot20
-rw-r--r--test/Analysis/exploded-graph-rewriter/environment.dot11
-rw-r--r--test/Analysis/exploded-graph-rewriter/environment_diff.dot42
-rw-r--r--test/Analysis/exploded-graph-rewriter/node_labels.dot43
-rw-r--r--test/Analysis/exploded-graph-rewriter/program_points.dot42
-rw-r--r--test/Analysis/exploded-graph-rewriter/store.dot15
-rw-r--r--test/Analysis/exploded-graph-rewriter/store_diff.dot37
-rw-r--r--test/Analysis/exploded-graph-rewriter/topology.dot14
-rw-r--r--test/Analysis/exploded-graph-rewriter/trimmers.dot40
-rwxr-xr-xutils/analyzer/exploded-graph-rewriter.py43
19 files changed, 305 insertions, 161 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 9773a552bf..e87772c04b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -131,10 +131,12 @@ class ExplodedNode : public llvm::FoldingSetNode {
/// Succs - The successors of this node.
NodeGroup Succs;
+ int64_t Id;
+
public:
explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
- bool IsSink)
- : Location(loc), State(std::move(state)), Succs(IsSink) {
+ int64_t Id, bool IsSink)
+ : Location(loc), State(std::move(state)), Succs(IsSink), Id(Id) {
assert(isSink() == IsSink);
}
@@ -258,7 +260,7 @@ public:
}
const_succ_range succs() const { return {Succs.begin(), Succs.end()}; }
- int64_t getID(ExplodedGraph *G) const;
+ int64_t getID() const { return Id; }
/// The node is trivial if it has only one successor, only one predecessor,
/// it's predecessor has only one successor,
@@ -324,7 +326,7 @@ protected:
BumpVectorContext BVC;
/// NumNodes - The number of nodes in the graph.
- unsigned NumNodes = 0;
+ int64_t NumNodes = 0;
/// A list of recently allocated nodes that can potentially be recycled.
NodeVector ChangedNodes;
@@ -358,6 +360,7 @@ public:
/// ExplodedGraph for further processing.
ExplodedNode *createUncachedNode(const ProgramPoint &L,
ProgramStateRef State,
+ int64_t Id,
bool IsSink = false);
std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
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"; },
diff --git a/test/Analysis/dump_egraph.c b/test/Analysis/dump_egraph.c
index 99463da3e7..4ad04002c4 100644
--- a/test/Analysis/dump_egraph.c
+++ b/test/Analysis/dump_egraph.c
@@ -18,7 +18,7 @@ int foo() {
return *x + *y;
}
-// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Edge\", \"src_id\": 2, \"dst_id\": 1, \"terminator\": null, \"term_kind\": null, \"tag\": null \}\l&nbsp;&nbsp;],\l&nbsp;&nbsp;\"program_state\": null
+// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Edge\", \"src_id\": 2, \"dst_id\": 1, \"terminator\": null, \"term_kind\": null, \"tag\": null, \"node_id\": 1, \"is_sink\":0, \"has_report\": 0 \}\l&nbsp;&nbsp;],\l&nbsp;&nbsp;\"program_state\": null
// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"BlockEntrance\", \"block_id\": 1
@@ -27,4 +27,4 @@ int foo() {
// CHECK: \"pretty\": \"'\\\\x13'\"
-// CHECK: \"has_report\": true
+// CHECK: \"has_report\": 1
diff --git a/test/Analysis/exploded-graph-rewriter/checker_messages.dot b/test/Analysis/exploded-graph-rewriter/checker_messages.dot
index 84185db5af..2d054a8d48 100644
--- a/test/Analysis/exploded-graph-rewriter/checker_messages.dot
+++ b/test/Analysis/exploded-graph-rewriter/checker_messages.dot
@@ -14,7 +14,14 @@ Node0x1 [shape=record,label=
"has_report": false,
"is_sink": false,
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"constraints": null,
diff --git a/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot b/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot
index 2f0bcbd4e5..898f79600b 100644
--- a/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot
@@ -5,12 +5,15 @@
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
- "state_id": 2,
- "program_points": [],
+ { "state_id": 2,
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"store": null,
@@ -59,12 +62,16 @@ Node0x1 -> Node0x4;
// CHECK-SAME: </tr>
Node0x4 [shape=record,label=
"{
- { "node_id": 4,
- "pointer": "0x4",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 5,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"store": null,
@@ -88,12 +95,15 @@ Node0x4 -> Node0x6;
Node0x6 [shape=record,label=
"{
- { "node_id": 6,
- "pointer": "0x6",
- "has_report": false,
- "is_sink": false,
- "state_id": 7,
- "program_points": [],
+ { "state_id": 7,
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": null
}
\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/constraints.dot b/test/Analysis/exploded-graph-rewriter/constraints.dot
index 075df98ce9..f5ebcf1a60 100644
--- a/test/Analysis/exploded-graph-rewriter/constraints.dot
+++ b/test/Analysis/exploded-graph-rewriter/constraints.dot
@@ -12,12 +12,16 @@
// CHECK-SAME: </table></td></tr>
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"environment": null,
diff --git a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
index 00b2f1456f..53a87aa667 100644
--- a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
@@ -5,12 +5,16 @@
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"environment": null,
@@ -39,12 +43,16 @@ Node0x1 -> Node0x3;
// CHECK-SAME: </tr>
Node0x3 [shape=record,label=
"{
- { "node_id": 3,
- "pointer": "0x3",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 4,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"environment": null,
@@ -62,12 +70,16 @@ Node0x3 -> Node0x5;
Node0x5 [shape=record,label=
"{
- { "node_id": 5,
- "pointer": "0x5",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 6,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"environment": null,
diff --git a/test/Analysis/exploded-graph-rewriter/edge.dot b/test/Analysis/exploded-graph-rewriter/edge.dot
index 15e55612b8..3923f1f8ee 100644
--- a/test/Analysis/exploded-graph-rewriter/edge.dot
+++ b/test/Analysis/exploded-graph-rewriter/edge.dot
@@ -5,13 +5,25 @@
// UNSUPPORTED: system-windows
Node0x1 [shape=record,label=
- "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
// LIGHT: Node0x1 -> Node0x2;
// DARK: Node0x1 -> Node0x2 [color="white"];
Node0x1 -> Node0x2;
Node0x2 [shape=record,label=
- "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/environment.dot b/test/Analysis/exploded-graph-rewriter/environment.dot
index 399484a7ee..733aae3036 100644
--- a/test/Analysis/exploded-graph-rewriter/environment.dot
+++ b/test/Analysis/exploded-graph-rewriter/environment.dot
@@ -11,7 +11,7 @@
// CHECK-SAME: </td>
// CHECK-SAME: <td align="left" colspan="2">
// CHECK-SAME: <font color="gray60">foo </font>
-// CHECK-SAME: (environment.cpp:<b>4</b>:<b>6</b>
+// CHECK-SAME: (environment.cpp:<b>4</b>:<b>6</b>
// CHECK-SAME: <font color="royalblue1">
// CHECK-SAME: (<i>spelling at </i> environment.h:<b>7</b>:<b>8</b>)
// CHECK-SAME: </font>)
@@ -36,7 +36,14 @@ Node0x1 [shape=record,label=
"has_report": false,
"is_sink": false,
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"constraints": null,
diff --git a/test/Analysis/exploded-graph-rewriter/environment_diff.dot b/test/Analysis/exploded-graph-rewriter/environment_diff.dot
index 475247bb98..05e8d4eef5 100644
--- a/test/Analysis/exploded-graph-rewriter/environment_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/environment_diff.dot
@@ -6,12 +6,16 @@
// No diffs on the first node, nothing to check.
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"constraints": null,
@@ -57,12 +61,16 @@ Node0x1 -> Node0x6;
// CHECK-SAME: </tr>
Node0x6 [shape=record,label=
"{
- { "node_id": 6,
- "pointer": "0x6",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 7,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"constraints": null,
@@ -102,12 +110,16 @@ Node0x6 -> Node0x9;
// CHECK-SAME: </tr>
Node0x9 [shape=record,label=
"{
- { "node_id": 9,
- "pointer": "0x9",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 7,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"store": null,
"constraints": null,
diff --git a/test/Analysis/exploded-graph-rewriter/node_labels.dot b/test/Analysis/exploded-graph-rewriter/node_labels.dot
index a434cd2307..a3d7420fed 100644
--- a/test/Analysis/exploded-graph-rewriter/node_labels.dot
+++ b/test/Analysis/exploded-graph-rewriter/node_labels.dot
@@ -15,30 +15,47 @@
// CHECK-SAME: <tr>
// LIGHT-SAME: <td bgcolor="gray70">
// DARK-SAME: <td bgcolor="gray20">
-// CHECK-SAME: <b>Node 1 (0x1) - State Unspecified</b>
+// CHECK-SAME: <b>State Unspecified</b>
// CHECK-SAME: </td>
// CHECK-SAME: </tr>
Node0x1 [shape=record,label=
"{
{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
"program_state": null,
- "program_points": []
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ]
}
\l}"];
// CHECK: Node0x2 [
-// CHECK-SAME: <tr><td>
-// COLOR-SAME: <font color="red"><b>Bug Report Attached</b></font>
-// GRAY-SAME: <b>Bug Report Attached</b>
-// CHECK-SAME: </td></tr>
-// CHECK-SAME: <tr><td>
-// COLOR-SAME: <font color="cornflowerblue"><b>Sink Node</b></font>
-// GRAY-SAME: <b>Sink Node</b>
-// CHECK-SAME: </td></tr>
+// CHECK-SAME: <tr>
+// CHECK-SAME: <td colspan="3" align="left">
+// COLOR-SAME: <font color="red"><b>Bug Report Attached</b></font>
+// GRAY-SAME: <b>Bug Report Attached</b>
+// CHECK-SAME: </td>
+// CHECK-SAME: </tr>
+// CHECK-SAME: <tr>
+// CHECK-SAME: <td colspan="3" align="left">
+// COLOR-SAME: <font color="cornflowerblue"><b>Sink Node</b></font>
+// GRAY-SAME: <b>Sink Node</b>
+// CHECK-SAME: </td>
+// CHECK-SAME: </tr>
Node0x2 [shape=record,label=
"{
- { "node_id": 2, "pointer": "0x2", "has_report": true, "is_sink": true,
- "program_state": null,
- "program_points": []
+ { "program_state": null,
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 2,
+ "has_report": 1, "is_sink": 1
+ }
+ ]
}
\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/program_points.dot b/test/Analysis/exploded-graph-rewriter/program_points.dot
index c27c230ebf..c9492757c3 100644
--- a/test/Analysis/exploded-graph-rewriter/program_points.dot
+++ b/test/Analysis/exploded-graph-rewriter/program_points.dot
@@ -28,7 +28,7 @@
// CHECK-SAME: </table>
Node0x1 [shape=record,label=
"{
- { "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
+ {
"program_state": null, "program_points": [
{
"kind": "Edge",
@@ -36,14 +36,20 @@ Node0x1 [shape=record,label=
"dst_id": 1,
"terminator": null,
"term_kind": null,
- "tag": null
+ "tag": null,
+ "node_id": 1,
+ "has_report": 0,
+ "is_sink": 0
},
{
"kind": "BlockEntrance",
"block_id": 1,
"terminator": null,
"term_kind": null,
- "tag": null
+ "tag": null,
+ "node_id": 2,
+ "has_report": 0,
+ "is_sink": 0
}
]}
\l}"];
@@ -72,10 +78,9 @@ Node0x1 [shape=record,label=
// CHECK-SAME: </td>
// CHECK-SAME: </tr>
// CHECK-SAME: </table>
-Node0x2 [shape=record,label=
+Node0x3 [shape=record,label=
"{
- { "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": [
+ { "program_state": null, "program_points": [
{
"kind": "Statement",
"stmt_kind": "DeclRefExpr",
@@ -88,7 +93,11 @@ Node0x2 [shape=record,label=
"line": 4,
"column": 5
},
- "tag": "ExprEngine : Clean Node"
+ "tag": "ExprEngine : Clean Node",
+ "node_id": 3,
+ "pointer": "0x3",
+ "has_report": 0,
+ "is_sink": 0
}
]}
\l}"];
@@ -97,9 +106,9 @@ Node0x2 [shape=record,label=
// CHECK-NEXT: <b>Program point:</b>
// CHECK-SAME: <td align="left">\{ ... \}</td>
-Node0x3 [shape=record,label=
+Node0x4 [shape=record,label=
"{
- { "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
+ {
"program_state": null, "program_points": [
{
"kind": "Statement",
@@ -112,7 +121,10 @@ Node0x3 [shape=record,label=
"line": 7,
"column": 8
},
- "tag": "ExprEngine : Clean Node"
+ "tag": "ExprEngine : Clean Node",
+ "node_id": 4,
+ "has_report": 0,
+ "is_sink": 0
}
]}
\l}"];
@@ -143,10 +155,9 @@ Node0x3 [shape=record,label=
// CHECK-SAME: </td>
// CHECK-SAME: </tr>
// CHECK-SAME: </table>
-Node0x4 [shape=record,label=
+Node0x5 [shape=record,label=
"{
- { "node_id": 4, "pointer": "0x4", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": [
+ { "program_state": null, "program_points": [
{
"kind": "Statement",
"stmt_kind": "ImplicitCastExpr",
@@ -160,7 +171,10 @@ Node0x4 [shape=record,label=
"line": 8,
"column": 9
},
- "tag": "ExprEngine : Clean Node"
+ "tag": "ExprEngine : Clean Node",
+ "node_id": 5,
+ "has_report": 0,
+ "is_sink": 0
}
]}
\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/store.dot b/test/Analysis/exploded-graph-rewriter/store.dot
index 7267dd43e8..c92901cbd7 100644
--- a/test/Analysis/exploded-graph-rewriter/store.dot
+++ b/test/Analysis/exploded-graph-rewriter/store.dot
@@ -23,12 +23,15 @@
// CHECK-SAME: </table>
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
- "state_id": 2,
- "program_points": [],
+ { "state_id": 2,
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"constraints": null,
diff --git a/test/Analysis/exploded-graph-rewriter/store_diff.dot b/test/Analysis/exploded-graph-rewriter/store_diff.dot
index 94d1d8d9f1..8dd5fb44cd 100644
--- a/test/Analysis/exploded-graph-rewriter/store_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/store_diff.dot
@@ -10,7 +10,14 @@ Node0x1 [shape=record,label=
"has_report": false,
"is_sink": false,
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"constraints": null,
@@ -55,12 +62,16 @@ Node0x1 -> Node0x4;
// CHECK-SAME: </tr>
Node0x4 [shape=record,label=
"{
- { "node_id": 4,
- "pointer": "0x4",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 5,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"constraints": null,
@@ -91,12 +102,16 @@ Node0x4 -> Node0x6;
Node0x6 [shape=record,label=
"{
- { "node_id": 6,
- "pointer": "0x6",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 7,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": null
}
\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/topology.dot b/test/Analysis/exploded-graph-rewriter/topology.dot
index fa1b10f68b..b85115ebea 100644
--- a/test/Analysis/exploded-graph-rewriter/topology.dot
+++ b/test/Analysis/exploded-graph-rewriter/topology.dot
@@ -12,12 +12,16 @@
// TOPOLOGY-NOT: Checker State
Node0x1 [shape=record,label=
"{
- { "node_id": 1,
- "pointer": "0x1",
- "has_report": false,
- "is_sink": false,
+ {
"state_id": 2,
- "program_points": [],
+ "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ],
"program_state": {
"environment": null,
"constraints": null,
diff --git a/test/Analysis/exploded-graph-rewriter/trimmers.dot b/test/Analysis/exploded-graph-rewriter/trimmers.dot
index 8bdef649e0..2c441e02c7 100644
--- a/test/Analysis/exploded-graph-rewriter/trimmers.dot
+++ b/test/Analysis/exploded-graph-rewriter/trimmers.dot
@@ -17,20 +17,44 @@
// UNSUPPORTED: system-windows
Node0x1 [shape=record,label=
- "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 1,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
Node0x2 [shape=record,label=
- "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 2,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
Node0x3 [shape=record,label=
- "{{ "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 3,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
Node0x4 [shape=record,label=
- "{{ "node_id": 4, "pointer": "0x4", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
+ "{{ "program_state": null, "program_points": [
+ {
+ "kind": "BlockEntrance", "block_id": 1,
+ "terminator": null, "term_kind": null,
+ "tag": null, "node_id": 4,
+ "has_report": 0, "is_sink": 0
+ }
+ ]}\l}"];
Node0x1 -> Node0x2;
Node0x1 -> Node0x3;
diff --git a/utils/analyzer/exploded-graph-rewriter.py b/utils/analyzer/exploded-graph-rewriter.py
index 77da7392e3..79222bdbe9 100755
--- a/utils/analyzer/exploded-graph-rewriter.py
+++ b/utils/analyzer/exploded-graph-rewriter.py
@@ -67,6 +67,9 @@ class ProgramPoint(object):
super(ProgramPoint, self).__init__()
self.kind = json_pp['kind']
self.tag = json_pp['tag']
+ self.node_id = json_pp['node_id']
+ self.is_sink = bool(json_pp['is_sink'])
+ self.has_report = bool(json_pp['has_report'])
if self.kind == 'Edge':
self.src_id = json_pp['src_id']
self.dst_id = json_pp['dst_id']
@@ -309,11 +312,9 @@ class ExplodedNode(object):
def construct(self, node_id, json_node):
logging.debug('Adding ' + node_id)
- self.node_id = json_node['node_id']
- self.ptr = json_node['pointer']
- self.has_report = json_node['has_report']
- self.is_sink = json_node['is_sink']
+ self.ptr = node_id[4:]
self.points = [ProgramPoint(p) for p in json_node['program_points']]
+ self.node_id = self.points[-1].node_id
self.state = ProgramState(json_node['state_id'],
json_node['program_state']) \
if json_node['program_state'] is not None else None
@@ -488,12 +489,14 @@ class DotDumpVisitor(object):
else:
color = 'forestgreen'
+ self._dump('<tr><td align="left">%s.</td>' % p.node_id)
+
if p.kind == 'Statement':
# This avoids pretty-printing huge statements such as CompoundStmt.
# Such statements show up only at [Pre|Post]StmtPurgeDeadSymbols
skip_pretty = 'PurgeDeadSymbols' in p.stmt_point_kind
stmt_color = 'cyan3'
- self._dump('<tr><td align="left" width="0">%s:</td>'
+ self._dump('<td align="left" width="0">%s:</td>'
'<td align="left" width="0"><font color="%s">'
'%s</font> </td>'
'<td align="left"><i>S%s</i></td>'
@@ -506,30 +509,41 @@ class DotDumpVisitor(object):
self._short_pretty(p.pretty)
if not skip_pretty else ''))
elif p.kind == 'Edge':
- self._dump('<tr><td width="0"></td>'
+ self._dump('<td width="0"></td>'
'<td align="left" width="0">'
'<font color="%s">%s</font></td><td align="left">'
'[B%d] -\\> [B%d]</td></tr>'
% (color, 'BlockEdge', p.src_id, p.dst_id))
elif p.kind == 'BlockEntrance':
- self._dump('<tr><td width="0"></td>'
+ self._dump('<td width="0"></td>'
'<td align="left" width="0">'
'<font color="%s">%s</font></td>'
'<td align="left">[B%d]</td></tr>'
% (color, p.kind, p.block_id))
else:
# TODO: Print more stuff for other kinds of points.
- self._dump('<tr><td width="0"></td>'
+ self._dump('<td width="0"></td>'
'<td align="left" width="0" colspan="2">'
'<font color="%s">%s</font></td></tr>'
% (color, p.kind))
if p.tag is not None:
- self._dump('<tr><td width="0"></td>'
+ self._dump('<tr><td width="0"></td><td width="0"></td>'
'<td colspan="3" align="left">'
'<b>Tag: </b> <font color="crimson">'
'%s</font></td></tr>' % p.tag)
+ if p.has_report:
+ self._dump('<tr><td width="0"></td><td width="0"></td>'
+ '<td colspan="3" align="left">'
+ '<font color="red"><b>Bug Report Attached'
+ '</b></font></td></tr>')
+ if p.is_sink:
+ self._dump('<tr><td width="0"></td><td width="0"></td>'
+ '<td colspan="3" align="left">'
+ '<font color="cornflowerblue"><b>Sink Node'
+ '</b></font></td></tr>')
+
def visit_environment(self, e, prev_e=None):
self._dump('<table border="0">')
@@ -786,17 +800,10 @@ class DotDumpVisitor(object):
self._dump('color="white",fontcolor="gray80",')
self._dump('label=<<table border="0">')
- self._dump('<tr><td bgcolor="%s"><b>Node %d (%s) - '
- 'State %s</b></td></tr>'
+ self._dump('<tr><td bgcolor="%s"><b>State %s</b></td></tr>'
% ("gray20" if self._dark_mode else "gray70",
- node.node_id, node.ptr, node.state.state_id
+ node.state.state_id
if node.state is not None else 'Unspecified'))
- if node.has_report:
- self._dump('<tr><td><font color="red"><b>Bug Report Attached'
- '</b></font></td></tr>')
- if node.is_sink:
- self._dump('<tr><td><font color="cornflowerblue"><b>Sink Node'
- '</b></font></td></tr>')
if not self._topo_mode:
self._dump('<tr><td align="left" width="0">')
if len(node.points) > 1: