forked from OSchip/llvm-project
[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
This commit is contained in:
parent
5fcf92e153
commit
ab758ba128
|
@ -3006,7 +3006,8 @@ struct DOTGraphTraits<ExplodedGraph*> : 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<ExplodedGraph*> : public DefaultDOTGraphTraits {
|
|||
return false;
|
||||
}
|
||||
|
||||
static std::string getNodeAttributes(const ExplodedNode *N,
|
||||
ExplodedGraph *) {
|
||||
SmallVector<StringRef, 10> 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<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\": " << (nodeHasBugReport(N) ? "true" : "false")
|
||||
<< ", \"has_report\": " << (HasReport ? "true" : "false")
|
||||
<< ", \"is_sink\": " << (IsSink ? "true" : "false")
|
||||
<< ",\\l";
|
||||
|
||||
Indent(Out, Space, IsDot) << "\"program_points\": [\\l";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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}"];
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -15,7 +15,22 @@
|
|||
// CHECK-SAME: </tr>
|
||||
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: <tr><td>
|
||||
// CHECK-SAME: <font color="red"><b>Bug Report Attached</b></font>
|
||||
// CHECK-SAME: </td></tr>
|
||||
// CHECK-SAME: <tr><td>
|
||||
// CHECK-SAME: <font color="cornflowerblue"><b>Sink Node</b></font>
|
||||
// CHECK-SAME: </td></tr>
|
||||
Node0x2 [shape=record,label=
|
||||
"{
|
||||
{ "node_id": 2, "pointer": "0x2", "has_report": true, "is_sink": true,
|
||||
"program_state": null,
|
||||
"program_points": []
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
// CHECK-SAME: </table>
|
||||
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: </table>
|
||||
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: <td>\{ ... \}</td>
|
||||
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",
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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('<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>')
|
||||
self._dump('<tr><td align="left" width="0">')
|
||||
if len(node.points) > 1:
|
||||
self._dump('<b>Program points:</b></td></tr>')
|
||||
|
|
Loading…
Reference in New Issue