Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -131,10 +131,12 @@ /// 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 @@ } 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 @@ 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 @@ /// ExplodedGraph for further processing. ExplodedNode *createUncachedNode(const ProgramPoint &L, ProgramStateRef State, + int64_t Id, bool IsSink = false); std::unique_ptr MakeEmptyGraph() const { Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2566,7 +2566,8 @@ // 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) Index: clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -283,10 +283,6 @@ return Storage.getAddrOfPtr1() + 1; } -int64_t ExplodedNode::getID(ExplodedGraph *G) const { - return G->getAllocator().identifyKnownAlignedObject(this); -} - bool ExplodedNode::isTrivial() const { return pred_size() == 1 && succ_size() == 1 && getFirstPred()->getState()->getID() == getState()->getID() && @@ -417,14 +413,14 @@ V = (NodeTy*) getAllocator().Allocate(); } - 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::createUncachedNode(const ProgramPoint &L, ProgramStateRef State, + int64_t Id, bool IsSink) { NodeTy *V = (NodeTy *) getAllocator().Allocate(); - new (V) NodeTy(L, State, IsSink); + new (V) NodeTy(L, State, Id, IsSink); return V; } @@ -498,7 +495,8 @@ // 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. Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3061,16 +3061,7 @@ 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 @@ 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"; }, Index: clang/test/Analysis/dump_egraph.c =================================================================== --- clang/test/Analysis/dump_egraph.c +++ clang/test/Analysis/dump_egraph.c @@ -18,7 +18,7 @@ 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 @@ // CHECK: \"pretty\": \"'\\\\x13'\" -// CHECK: \"has_report\": true +// CHECK: \"has_report\": 1 Index: clang/test/Analysis/exploded-graph-rewriter/checker_messages.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/checker_messages.dot +++ clang/test/Analysis/exploded-graph-rewriter/checker_messages.dot @@ -14,7 +14,14 @@ "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, Index: clang/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot +++ clang/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 @@ // CHECK-SAME: 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 @@ 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}"]; Index: clang/test/Analysis/exploded-graph-rewriter/constraints.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/constraints.dot +++ clang/test/Analysis/exploded-graph-rewriter/constraints.dot @@ -12,12 +12,16 @@ // CHECK-SAME: 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, Index: clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot +++ clang/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 @@ // CHECK-SAME: 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 @@ 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, Index: clang/test/Analysis/exploded-graph-rewriter/edge.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/edge.dot +++ clang/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}"]; Index: clang/test/Analysis/exploded-graph-rewriter/environment.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/environment.dot +++ clang/test/Analysis/exploded-graph-rewriter/environment.dot @@ -11,7 +11,7 @@ // CHECK-SAME: // CHECK-SAME: // CHECK-SAME: foo -// CHECK-SAME: (environment.cpp:4:6 +// CHECK-SAME: (environment.cpp:4:6 // CHECK-SAME: // CHECK-SAME: (spelling at environment.h:7:8) // CHECK-SAME: ) @@ -36,7 +36,14 @@ "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, Index: clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot +++ clang/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 @@ // CHECK-SAME: 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 @@ // CHECK-SAME: 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, Index: clang/test/Analysis/exploded-graph-rewriter/node_labels.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/node_labels.dot +++ clang/test/Analysis/exploded-graph-rewriter/node_labels.dot @@ -15,30 +15,47 @@ // CHECK-SAME: // LIGHT-SAME: // DARK-SAME: -// CHECK-SAME: Node 1 (0x1) - State Unspecified +// CHECK-SAME: State Unspecified // CHECK-SAME: // CHECK-SAME: 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: -// COLOR-SAME: Bug Report Attached -// GRAY-SAME: Bug Report Attached -// CHECK-SAME: -// CHECK-SAME: -// COLOR-SAME: Sink Node -// GRAY-SAME: Sink Node -// CHECK-SAME: +// CHECK-SAME: +// CHECK-SAME: +// COLOR-SAME: Bug Report Attached +// GRAY-SAME: Bug Report Attached +// CHECK-SAME: +// CHECK-SAME: +// CHECK-SAME: +// CHECK-SAME: +// COLOR-SAME: Sink Node +// GRAY-SAME: Sink Node +// CHECK-SAME: +// CHECK-SAME: 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}"]; Index: clang/test/Analysis/exploded-graph-rewriter/program_points.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/program_points.dot +++ clang/test/Analysis/exploded-graph-rewriter/program_points.dot @@ -28,7 +28,7 @@ // CHECK-SAME: 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 @@ "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 @@ // CHECK-SAME: // CHECK-SAME: // CHECK-SAME: -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 @@ "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 @@ // CHECK-NEXT: Program point: // CHECK-SAME: \{ ... \} -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 @@ "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 @@ // CHECK-SAME: // CHECK-SAME: // CHECK-SAME: -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 @@ "line": 8, "column": 9 }, - "tag": "ExprEngine : Clean Node" + "tag": "ExprEngine : Clean Node", + "node_id": 5, + "has_report": 0, + "is_sink": 0 } ]} \l}"]; Index: clang/test/Analysis/exploded-graph-rewriter/store.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/store.dot +++ clang/test/Analysis/exploded-graph-rewriter/store.dot @@ -23,12 +23,15 @@ // CHECK-SAME: 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, Index: clang/test/Analysis/exploded-graph-rewriter/store_diff.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/store_diff.dot +++ clang/test/Analysis/exploded-graph-rewriter/store_diff.dot @@ -10,7 +10,14 @@ "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 @@ // CHECK-SAME: 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 @@ 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}"]; Index: clang/test/Analysis/exploded-graph-rewriter/topology.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/topology.dot +++ clang/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, Index: clang/test/Analysis/exploded-graph-rewriter/trimmers.dot =================================================================== --- clang/test/Analysis/exploded-graph-rewriter/trimmers.dot +++ clang/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; Index: clang/utils/analyzer/exploded-graph-rewriter.py =================================================================== --- clang/utils/analyzer/exploded-graph-rewriter.py +++ clang/utils/analyzer/exploded-graph-rewriter.py @@ -67,6 +67,9 @@ 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 @@ 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 @@ else: color = 'forestgreen' + self._dump('%s.' % 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('%s:' + self._dump('%s:' '' '%s ' 'S%s' @@ -506,30 +509,41 @@ self._short_pretty(p.pretty) if not skip_pretty else '')) elif p.kind == 'Edge': - self._dump('' + self._dump('' '' '%s' '[B%d] -\\> [B%d]' % (color, 'BlockEdge', p.src_id, p.dst_id)) elif p.kind == 'BlockEntrance': - self._dump('' + self._dump('' '' '%s' '[B%d]' % (color, p.kind, p.block_id)) else: # TODO: Print more stuff for other kinds of points. - self._dump('' + self._dump('' '' '%s' % (color, p.kind)) if p.tag is not None: - self._dump('' + self._dump('' '' 'Tag: ' '%s' % p.tag) + if p.has_report: + self._dump('' + '' + 'Bug Report Attached' + '') + if p.is_sink: + self._dump('' + '' + 'Sink Node' + '') + def visit_environment(self, e, prev_e=None): self._dump('') @@ -786,17 +800,10 @@ self._dump('color="white",fontcolor="gray80",') self._dump('label=<
') - self._dump('' + self._dump('' % ("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('') - if node.is_sink: - self._dump('') if not self._topo_mode: self._dump('
Node %d (%s) - ' - 'State %s
State %s
Bug Report Attached' - '
Sink Node' - '
') if len(node.points) > 1: