From: Artem Dergachev Date: Wed, 3 Jul 2019 01:26:41 +0000 (+0000) Subject: [analyzer] exploded-graph-rewriter: Implement bug nodes and sink nodes. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ed0749151866894a67a3e7eefdc1f3a547daa0e;p=clang [analyzer] exploded-graph-rewriter: Implement bug nodes and sink nodes. Add a label to nodes that have a bug report attached or on which the analysis was generally interrupted. Fix printing has_report and implement printing is_sink in the graph dumper. Differential Revision: https://reviews.llvm.org/D64110 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@364992 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index d95fb314f3..12094c6a1e 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3006,7 +3006,8 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { 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 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { 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 @@ struct DOTGraphTraits : 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\": " << (nodeHasBugReport(N) ? "true" : "false") + << ", \"has_report\": " << (HasReport ? "true" : "false") + << ", \"is_sink\": " << (IsSink ? "true" : "false") << ",\\l"; Indent(Out, Space, IsDot) << "\"program_points\": [\\l"; diff --git a/test/Analysis/dump_egraph.c b/test/Analysis/dump_egraph.c index 1134375303..99463da3e7 100644 --- a/test/Analysis/dump_egraph.c +++ b/test/Analysis/dump_egraph.c @@ -22,9 +22,9 @@ int foo() { // 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 diff --git a/test/Analysis/exploded-graph-rewriter/checker_messages.dot b/test/Analysis/exploded-graph-rewriter/checker_messages.dot index e7a7d7131d..84185db5af 100644 --- a/test/Analysis/exploded-graph-rewriter/checker_messages.dot +++ b/test/Analysis/exploded-graph-rewriter/checker_messages.dot @@ -11,6 +11,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot b/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot index 57cbb5e83a..2f0bcbd4e5 100644 --- a/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot +++ b/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot @@ -7,6 +7,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -59,6 +61,8 @@ Node0x4 [shape=record,label= "{ { "node_id": 4, "pointer": "0x4", + "has_report": false, + "is_sink": false, "state_id": 5, "program_points": [], "program_state": { @@ -86,6 +90,8 @@ Node0x6 [shape=record,label= "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": null diff --git a/test/Analysis/exploded-graph-rewriter/constraints.dot b/test/Analysis/exploded-graph-rewriter/constraints.dot index 10e72d67df..075df98ce9 100644 --- a/test/Analysis/exploded-graph-rewriter/constraints.dot +++ b/test/Analysis/exploded-graph-rewriter/constraints.dot @@ -14,6 +14,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot index cd7bc62299..00b2f1456f 100644 --- a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot +++ b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot @@ -7,6 +7,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -39,6 +41,8 @@ Node0x3 [shape=record,label= "{ { "node_id": 3, "pointer": "0x3", + "has_report": false, + "is_sink": false, "state_id": 4, "program_points": [], "program_state": { @@ -60,6 +64,8 @@ Node0x5 [shape=record,label= "{ { "node_id": 5, "pointer": "0x5", + "has_report": false, + "is_sink": false, "state_id": 6, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/edge.dot b/test/Analysis/exploded-graph-rewriter/edge.dot index 2d3a4fe7bd..15e55612b8 100644 --- a/test/Analysis/exploded-graph-rewriter/edge.dot +++ b/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 [shape=record,label= 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}"]; diff --git a/test/Analysis/exploded-graph-rewriter/environment.dot b/test/Analysis/exploded-graph-rewriter/environment.dot index 4167a8c4cb..2b8a402cd8 100644 --- a/test/Analysis/exploded-graph-rewriter/environment.dot +++ b/test/Analysis/exploded-graph-rewriter/environment.dot @@ -29,6 +29,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/environment_diff.dot b/test/Analysis/exploded-graph-rewriter/environment_diff.dot index a624910330..c3ba88622f 100644 --- a/test/Analysis/exploded-graph-rewriter/environment_diff.dot +++ b/test/Analysis/exploded-graph-rewriter/environment_diff.dot @@ -8,6 +8,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -57,6 +59,8 @@ Node0x6 [shape=record,label= "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": { @@ -100,6 +104,8 @@ Node0x9 [shape=record,label= "{ { "node_id": 9, "pointer": "0x9", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/node_labels.dot b/test/Analysis/exploded-graph-rewriter/node_labels.dot index 60b2b29c06..db56c0585c 100644 --- a/test/Analysis/exploded-graph-rewriter/node_labels.dot +++ b/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": [] } diff --git a/test/Analysis/exploded-graph-rewriter/program_points.dot b/test/Analysis/exploded-graph-rewriter/program_points.dot index d7f69696fd..342a923725 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: 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 @@ Node0x1 [shape=record,label= // 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 @@ Node0x2 [shape=record,label= // 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", diff --git a/test/Analysis/exploded-graph-rewriter/store.dot b/test/Analysis/exploded-graph-rewriter/store.dot index 8331d099c0..d47a02295e 100644 --- a/test/Analysis/exploded-graph-rewriter/store.dot +++ b/test/Analysis/exploded-graph-rewriter/store.dot @@ -24,6 +24,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { diff --git a/test/Analysis/exploded-graph-rewriter/store_diff.dot b/test/Analysis/exploded-graph-rewriter/store_diff.dot index f8dfe51178..94d1d8d9f1 100644 --- a/test/Analysis/exploded-graph-rewriter/store_diff.dot +++ b/test/Analysis/exploded-graph-rewriter/store_diff.dot @@ -7,6 +7,8 @@ Node0x1 [shape=record,label= "{ { "node_id": 1, "pointer": "0x1", + "has_report": false, + "is_sink": false, "state_id": 2, "program_points": [], "program_state": { @@ -55,6 +57,8 @@ Node0x4 [shape=record,label= "{ { "node_id": 4, "pointer": "0x4", + "has_report": false, + "is_sink": false, "state_id": 5, "program_points": [], "program_state": { @@ -89,6 +93,8 @@ Node0x6 [shape=record,label= "{ { "node_id": 6, "pointer": "0x6", + "has_report": false, + "is_sink": false, "state_id": 7, "program_points": [], "program_state": null diff --git a/utils/analyzer/exploded-graph-rewriter.py b/utils/analyzer/exploded-graph-rewriter.py index 463ae02fe8..0926ba2511 100755 --- a/utils/analyzer/exploded-graph-rewriter.py +++ b/utils/analyzer/exploded-graph-rewriter.py @@ -299,6 +299,8 @@ class ExplodedNode(object): 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 @@ class DotDumpVisitor(object): % ("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:')