]> granicus.if.org Git - clang/commitdiff
[analyzer] exploded-graph-rewriter: Implement bug nodes and sink nodes.
authorArtem Dergachev <artem.dergachev@gmail.com>
Wed, 3 Jul 2019 01:26:41 +0000 (01:26 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Wed, 3 Jul 2019 01:26:41 +0000 (01:26 +0000)
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

14 files changed:
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/dump_egraph.c
test/Analysis/exploded-graph-rewriter/checker_messages.dot
test/Analysis/exploded-graph-rewriter/checker_messages_diff.dot
test/Analysis/exploded-graph-rewriter/constraints.dot
test/Analysis/exploded-graph-rewriter/constraints_diff.dot
test/Analysis/exploded-graph-rewriter/edge.dot
test/Analysis/exploded-graph-rewriter/environment.dot
test/Analysis/exploded-graph-rewriter/environment_diff.dot
test/Analysis/exploded-graph-rewriter/node_labels.dot
test/Analysis/exploded-graph-rewriter/program_points.dot
test/Analysis/exploded-graph-rewriter/store.dot
test/Analysis/exploded-graph-rewriter/store_diff.dot
utils/analyzer/exploded-graph-rewriter.py

index d95fb314f3c911f4037b480d22313a56a9f44ba5..12094c6a1e6c9096d17119271abe8b15ca1628af 100644 (file)
@@ -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";
index 11343753037b24536ede4ae6fa49f38fdbaf3644..99463da3e798e236c626435658964903b6465a1e 100644 (file)
@@ -22,9 +22,9 @@ int foo() {
 
 // CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"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 e7a7d7131d9780c6b2da65540c2f353314168d88..84185db5af617c1b99781085eb1c6dad4144c9c9 100644 (file)
@@ -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": {
index 57cbb5e83ad2f57267c7582c5f17a09ff5cde0c9..2f0bcbd4e5f2fe0b178dbc8de4158c62f964beed 100644 (file)
@@ -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
index 10e72d67df7ca336eab33fefb756db814a814ff4..075df98ce942e5d7b291b6b0dd5b49d009d0b2e4 100644 (file)
@@ -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": {
index cd7bc62299dd6af14aac8ba26f156c08c0da14f8..00b2f1456f31392398e40a46805199b7abc21622 100644 (file)
@@ -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": {
index 2d3a4fe7bd7aac80dda23ed673f96a0fdfa865a9..15e55612b803710e0c8c0ff89a28939617879bdf 100644 (file)
@@ -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}"];
index 4167a8c4cb76c5ceac18889d53896c59b1a6e902..2b8a402cd8eb66c0c3f6ec18d54b0be64a976ec1 100644 (file)
@@ -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": {
index a624910330abfe91093697f6925f428d78b46af7..c3ba88622f1f0841261b973f79642f2443fb622c 100644 (file)
@@ -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": {
index 60b2b29c06583add86906ee1c00cef7b64403e09..db56c0585c1feae2af633c80ca8b1da3d1b381c7 100644 (file)
 // 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": []
     }
index d7f69696fd3a0bb589a94d8d0c62a38312d0fab8..342a923725ec5e8b0d26ab16a8c225e44d0b5c35 100644 (file)
@@ -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",
index 8331d099c050a935bf917139e288e8c2f6f5416a..d47a02295e4934fce92cf3284443a1f4e335e274 100644 (file)
@@ -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": {
index f8dfe5117835830d8a10aade2014ab84e32f23a5..94d1d8d9f1f5bf318fa08caea6e0942b59f1581d 100644 (file)
@@ -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
index 463ae02fe8611156a678f815576da2169861ac70..0926ba2511ee70f71168d045e275657d6e6843aa 100755 (executable)
@@ -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>')