diff options
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 \{ \"kind\": \"Edge\", \"src_id\": 2, \"dst_id\": 1, \"terminator\": null, \"term_kind\": null, \"tag\": null \}\l ],\l \"program_state\": null +// CHECK: \"program_points\": [\l \{ \"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 ],\l \"program_state\": null // CHECK: \"program_points\": [\l \{ \"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: |