Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3006,7 +3006,8 @@ for (const auto &EQ : EQClasses) { for (const BugReport &Report : EQ) { - if (Report.getErrorNode()->getState() == N->getState()) + if (Report.getErrorNode()->getState() == N->getState() && + Report.getErrorNode()->getLocation() == N->getLocation()) return true; } } @@ -3042,21 +3043,6 @@ return false; } - static std::string getNodeAttributes(const ExplodedNode *N, - ExplodedGraph *) { - SmallVector Out; - auto Noop = [](const ExplodedNode*){}; - if (traverseHiddenNodes(N, Noop, Noop, &nodeHasBugReport)) { - Out.push_back("style=filled"); - Out.push_back("fillcolor=red"); - } - - if (traverseHiddenNodes(N, Noop, Noop, - [](const ExplodedNode *C) { return C->isSink(); })) - Out.push_back("color=blue"); - return llvm::join(Out, ","); - } - static bool isNodeHidden(const ExplodedNode *N) { return N->isTrivial(); } @@ -3069,9 +3055,16 @@ 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\": " << (nodeHasBugReport(N) ? "true" : "false") + << ", \"has_report\": " << (HasReport ? "true" : "false") + << ", \"is_sink\": " << (IsSink ? "true" : "false") << ",\\l"; Indent(Out, Space, IsDot) << "\"program_points\": [\\l"; Index: cfe/trunk/test/Analysis/dump_egraph.c =================================================================== --- cfe/trunk/test/Analysis/dump_egraph.c +++ cfe/trunk/test/Analysis/dump_egraph.c @@ -22,9 +22,9 @@ // CHECK: \"program_points\": [\l    \{ \"kind\": \"BlockEntrance\", \"block_id\": 1 -// CHECK: \"has_report\": true // CHECK: \"pretty\": \"*x\", \"location\": \{ \"line\": 18, \"column\": 10, \"file\": \"{{(.+)}}dump_egraph.c\" \} // CHECK: \"pretty\": \"'\\\\x13'\" +// CHECK: \"has_report\": true Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages.dot @@ -11,6 +11,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot @@ -7,6 +7,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -59,6 +61,8 @@ "{ { "node_id": 4, "pointer": "0x4", + "has_report": false, + "is_sink": false, "state_id": 5, "program_points": [], "program_state": { @@ -86,6 +90,8 @@ "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": null Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot @@ -14,6 +14,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot @@ -7,6 +7,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -39,6 +41,8 @@ "{ { "node_id": 3, "pointer": "0x3", + "has_report": false, + "is_sink": false, "state_id": 4, "program_points": [], "program_state": { @@ -60,6 +64,8 @@ "{ { "node_id": 5, "pointer": "0x5", + "has_report": false, + "is_sink": false, "state_id": 6, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/edge.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/edge.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/edge.dot @@ -5,7 +5,7 @@ // UNSUPPORTED: system-windows Node0x1 [shape=record,label= - "{{ "node_id": 1, "pointer": "0x1", + "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false, "program_state": null, "program_points": []}\l}"]; // LIGHT: Node0x1 -> Node0x2; @@ -13,5 +13,5 @@ Node0x1 -> Node0x2; Node0x2 [shape=record,label= - "{{ "node_id": 2, "pointer": "0x2", + "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false, "program_state": null, "program_points": []}\l}"]; Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot @@ -29,6 +29,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot @@ -8,6 +8,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -57,6 +59,8 @@ "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": { @@ -100,6 +104,8 @@ "{ { "node_id": 9, "pointer": "0x9", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/node_labels.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/node_labels.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/node_labels.dot @@ -15,7 +15,22 @@ // CHECK-SAME: Node0x1 [shape=record,label= "{ - { "node_id": 1, "pointer": "0x1", + { "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false, + "program_state": null, + "program_points": [] + } +\l}"]; + +// CHECK: Node0x2 [ +// CHECK-SAME: +// CHECK-SAME: Bug Report Attached +// CHECK-SAME: +// CHECK-SAME: +// CHECK-SAME: Sink Node +// CHECK-SAME: +Node0x2 [shape=record,label= + "{ + { "node_id": 2, "pointer": "0x2", "has_report": true, "is_sink": true, "program_state": null, "program_points": [] } Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/program_points.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/program_points.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/program_points.dot @@ -28,7 +28,7 @@ // CHECK-SAME: Node0x1 [shape=record,label= "{ - { "node_id": 1, "pointer": "0x1", + { "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false, "program_state": null, "program_points": [ { "kind": "Edge", @@ -73,7 +73,7 @@ // CHECK-SAME: Node0x2 [shape=record,label= "{ - { "node_id": 2, "pointer": "0x2", + { "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false, "program_state": null, "program_points": [ { "kind": "Statement", @@ -97,7 +97,7 @@ // CHECK-SAME: \{ ... \} Node0x3 [shape=record,label= "{ - { "node_id": 3, "pointer": "0x3", + { "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false, "program_state": null, "program_points": [ { "kind": "Statement", Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot @@ -24,6 +24,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { Index: cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot =================================================================== --- cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot +++ cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot @@ -7,6 +7,8 @@ "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -55,6 +57,8 @@ "{ { "node_id": 4, "pointer": "0x4", + "has_report": false, + "is_sink": false, "state_id": 5, "program_points": [], "program_state": { @@ -89,6 +93,8 @@ "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": null Index: cfe/trunk/utils/analyzer/exploded-graph-rewriter.py =================================================================== --- cfe/trunk/utils/analyzer/exploded-graph-rewriter.py +++ cfe/trunk/utils/analyzer/exploded-graph-rewriter.py @@ -299,6 +299,8 @@ 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.points = [ProgramPoint(p) for p in json_node['program_points']] self.state = ProgramState(json_node['state_id'], json_node['program_state']) \ @@ -754,6 +756,12 @@ % ("gray20" if self._dark_mode else "gray", node.node_id, node.ptr, node.state.state_id if node.state is not None else 'Unspecified')) + if node.has_report: + self._dump('Bug Report Attached' + '') + if node.is_sink: + self._dump('Sink Node' + '') self._dump('') if len(node.points) > 1: self._dump('Program points:')