Skip to content

Commit ab758ba

Browse files
committed
[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 llvm-svn: 364992
1 parent 5fcf92e commit ab758ba

14 files changed

+72
-24
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,7 +3006,8 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
30063006

30073007
for (const auto &EQ : EQClasses) {
30083008
for (const BugReport &Report : EQ) {
3009-
if (Report.getErrorNode()->getState() == N->getState())
3009+
if (Report.getErrorNode()->getState() == N->getState() &&
3010+
Report.getErrorNode()->getLocation() == N->getLocation())
30103011
return true;
30113012
}
30123013
}
@@ -3042,21 +3043,6 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
30423043
return false;
30433044
}
30443045

3045-
static std::string getNodeAttributes(const ExplodedNode *N,
3046-
ExplodedGraph *) {
3047-
SmallVector<StringRef, 10> Out;
3048-
auto Noop = [](const ExplodedNode*){};
3049-
if (traverseHiddenNodes(N, Noop, Noop, &nodeHasBugReport)) {
3050-
Out.push_back("style=filled");
3051-
Out.push_back("fillcolor=red");
3052-
}
3053-
3054-
if (traverseHiddenNodes(N, Noop, Noop,
3055-
[](const ExplodedNode *C) { return C->isSink(); }))
3056-
Out.push_back("color=blue");
3057-
return llvm::join(Out, ",");
3058-
}
3059-
30603046
static bool isNodeHidden(const ExplodedNode *N) {
30613047
return N->isTrivial();
30623048
}
@@ -3069,9 +3055,16 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
30693055
const unsigned int Space = 1;
30703056
ProgramStateRef State = N->getState();
30713057

3058+
auto Noop = [](const ExplodedNode*){};
3059+
bool HasReport = traverseHiddenNodes(
3060+
N, Noop, Noop, &nodeHasBugReport);
3061+
bool IsSink = traverseHiddenNodes(
3062+
N, Noop, Noop, [](const ExplodedNode *N) { return N->isSink(); });
3063+
30723064
Out << "{ \"node_id\": " << N->getID(G) << ", \"pointer\": \""
30733065
<< (const void *)N << "\", \"state_id\": " << State->getID()
3074-
<< ", \"has_report\": " << (nodeHasBugReport(N) ? "true" : "false")
3066+
<< ", \"has_report\": " << (HasReport ? "true" : "false")
3067+
<< ", \"is_sink\": " << (IsSink ? "true" : "false")
30753068
<< ",\\l";
30763069

30773070
Indent(Out, Space, IsDot) << "\"program_points\": [\\l";

clang/test/Analysis/dump_egraph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ int foo() {
2222

2323
// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"BlockEntrance\", \"block_id\": 1
2424

25-
// CHECK: \"has_report\": true
2625

2726
// CHECK: \"pretty\": \"*x\", \"location\": \{ \"line\": 18, \"column\": 10, \"file\": \"{{(.+)}}dump_egraph.c\" \}
2827

2928
// CHECK: \"pretty\": \"'\\\\x13'\"
3029

30+
// CHECK: \"has_report\": true

clang/test/Analysis/exploded-graph-rewriter/checker_messages.dot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Node0x1 [shape=record,label=
1111
"{
1212
{ "node_id": 1,
1313
"pointer": "0x1",
14+
"has_report": false,
15+
"is_sink": false,
1416
"state_id": 2,
1517
"program_points": [],
1618
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Node0x1 [shape=record,label=
77
"{
88
{ "node_id": 1,
99
"pointer": "0x1",
10+
"has_report": false,
11+
"is_sink": false,
1012
"state_id": 2,
1113
"program_points": [],
1214
"program_state": {
@@ -59,6 +61,8 @@ Node0x4 [shape=record,label=
5961
"{
6062
{ "node_id": 4,
6163
"pointer": "0x4",
64+
"has_report": false,
65+
"is_sink": false,
6266
"state_id": 5,
6367
"program_points": [],
6468
"program_state": {
@@ -86,6 +90,8 @@ Node0x6 [shape=record,label=
8690
"{
8791
{ "node_id": 6,
8892
"pointer": "0x6",
93+
"has_report": false,
94+
"is_sink": false,
8995
"state_id": 7,
9096
"program_points": [],
9197
"program_state": null

clang/test/Analysis/exploded-graph-rewriter/constraints.dot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Node0x1 [shape=record,label=
1414
"{
1515
{ "node_id": 1,
1616
"pointer": "0x1",
17+
"has_report": false,
18+
"is_sink": false,
1719
"state_id": 2,
1820
"program_points": [],
1921
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Node0x1 [shape=record,label=
77
"{
88
{ "node_id": 1,
99
"pointer": "0x1",
10+
"has_report": false,
11+
"is_sink": false,
1012
"state_id": 2,
1113
"program_points": [],
1214
"program_state": {
@@ -39,6 +41,8 @@ Node0x3 [shape=record,label=
3941
"{
4042
{ "node_id": 3,
4143
"pointer": "0x3",
44+
"has_report": false,
45+
"is_sink": false,
4246
"state_id": 4,
4347
"program_points": [],
4448
"program_state": {
@@ -60,6 +64,8 @@ Node0x5 [shape=record,label=
6064
"{
6165
{ "node_id": 5,
6266
"pointer": "0x5",
67+
"has_report": false,
68+
"is_sink": false,
6369
"state_id": 6,
6470
"program_points": [],
6571
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/edge.dot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
// UNSUPPORTED: system-windows
66

77
Node0x1 [shape=record,label=
8-
"{{ "node_id": 1, "pointer": "0x1",
8+
"{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
99
"program_state": null, "program_points": []}\l}"];
1010

1111
// LIGHT: Node0x1 -> Node0x2;
1212
// DARK: Node0x1 -> Node0x2 [color="white"];
1313
Node0x1 -> Node0x2;
1414

1515
Node0x2 [shape=record,label=
16-
"{{ "node_id": 2, "pointer": "0x2",
16+
"{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
1717
"program_state": null, "program_points": []}\l}"];

clang/test/Analysis/exploded-graph-rewriter/environment.dot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Node0x1 [shape=record,label=
2929
"{
3030
{ "node_id": 1,
3131
"pointer": "0x1",
32+
"has_report": false,
33+
"is_sink": false,
3234
"state_id": 2,
3335
"program_points": [],
3436
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Node0x1 [shape=record,label=
88
"{
99
{ "node_id": 1,
1010
"pointer": "0x1",
11+
"has_report": false,
12+
"is_sink": false,
1113
"state_id": 2,
1214
"program_points": [],
1315
"program_state": {
@@ -57,6 +59,8 @@ Node0x6 [shape=record,label=
5759
"{
5860
{ "node_id": 6,
5961
"pointer": "0x6",
62+
"has_report": false,
63+
"is_sink": false,
6064
"state_id": 7,
6165
"program_points": [],
6266
"program_state": {
@@ -100,6 +104,8 @@ Node0x9 [shape=record,label=
100104
"{
101105
{ "node_id": 9,
102106
"pointer": "0x9",
107+
"has_report": false,
108+
"is_sink": false,
103109
"state_id": 7,
104110
"program_points": [],
105111
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/node_labels.dot

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,22 @@
1515
// CHECK-SAME: </tr>
1616
Node0x1 [shape=record,label=
1717
"{
18-
{ "node_id": 1, "pointer": "0x1",
18+
{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
19+
"program_state": null,
20+
"program_points": []
21+
}
22+
\l}"];
23+
24+
// CHECK: Node0x2 [
25+
// CHECK-SAME: <tr><td>
26+
// CHECK-SAME: <font color="red"><b>Bug Report Attached</b></font>
27+
// CHECK-SAME: </td></tr>
28+
// CHECK-SAME: <tr><td>
29+
// CHECK-SAME: <font color="cornflowerblue"><b>Sink Node</b></font>
30+
// CHECK-SAME: </td></tr>
31+
Node0x2 [shape=record,label=
32+
"{
33+
{ "node_id": 2, "pointer": "0x2", "has_report": true, "is_sink": true,
1934
"program_state": null,
2035
"program_points": []
2136
}

clang/test/Analysis/exploded-graph-rewriter/program_points.dot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
// CHECK-SAME: </table>
2929
Node0x1 [shape=record,label=
3030
"{
31-
{ "node_id": 1, "pointer": "0x1",
31+
{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
3232
"program_state": null, "program_points": [
3333
{
3434
"kind": "Edge",
@@ -73,7 +73,7 @@ Node0x1 [shape=record,label=
7373
// CHECK-SAME: </table>
7474
Node0x2 [shape=record,label=
7575
"{
76-
{ "node_id": 2, "pointer": "0x2",
76+
{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
7777
"program_state": null, "program_points": [
7878
{
7979
"kind": "Statement",
@@ -97,7 +97,7 @@ Node0x2 [shape=record,label=
9797
// CHECK-SAME: <td>\{ ... \}</td>
9898
Node0x3 [shape=record,label=
9999
"{
100-
{ "node_id": 3, "pointer": "0x3",
100+
{ "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
101101
"program_state": null, "program_points": [
102102
{
103103
"kind": "Statement",

clang/test/Analysis/exploded-graph-rewriter/store.dot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Node0x1 [shape=record,label=
2424
"{
2525
{ "node_id": 1,
2626
"pointer": "0x1",
27+
"has_report": false,
28+
"is_sink": false,
2729
"state_id": 2,
2830
"program_points": [],
2931
"program_state": {

clang/test/Analysis/exploded-graph-rewriter/store_diff.dot

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Node0x1 [shape=record,label=
77
"{
88
{ "node_id": 1,
99
"pointer": "0x1",
10+
"has_report": false,
11+
"is_sink": false,
1012
"state_id": 2,
1113
"program_points": [],
1214
"program_state": {
@@ -55,6 +57,8 @@ Node0x4 [shape=record,label=
5557
"{
5658
{ "node_id": 4,
5759
"pointer": "0x4",
60+
"has_report": false,
61+
"is_sink": false,
5862
"state_id": 5,
5963
"program_points": [],
6064
"program_state": {
@@ -89,6 +93,8 @@ Node0x6 [shape=record,label=
8993
"{
9094
{ "node_id": 6,
9195
"pointer": "0x6",
96+
"has_report": false,
97+
"is_sink": false,
9298
"state_id": 7,
9399
"program_points": [],
94100
"program_state": null

clang/utils/analyzer/exploded-graph-rewriter.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ def construct(self, node_id, json_node):
299299
logging.debug('Adding ' + node_id)
300300
self.node_id = json_node['node_id']
301301
self.ptr = json_node['pointer']
302+
self.has_report = json_node['has_report']
303+
self.is_sink = json_node['is_sink']
302304
self.points = [ProgramPoint(p) for p in json_node['program_points']]
303305
self.state = ProgramState(json_node['state_id'],
304306
json_node['program_state']) \
@@ -754,6 +756,12 @@ def visit_node(self, node):
754756
% ("gray20" if self._dark_mode else "gray",
755757
node.node_id, node.ptr, node.state.state_id
756758
if node.state is not None else 'Unspecified'))
759+
if node.has_report:
760+
self._dump('<tr><td><font color="red"><b>Bug Report Attached'
761+
'</b></font></td></tr>')
762+
if node.is_sink:
763+
self._dump('<tr><td><font color="cornflowerblue"><b>Sink Node'
764+
'</b></font></td></tr>')
757765
self._dump('<tr><td align="left" width="0">')
758766
if len(node.points) > 1:
759767
self._dump('<b>Program points:</b></td></tr>')

0 commit comments

Comments
 (0)