[clang] 01f9388 - [analyzer] Handle `\l` symbol in string literals in exploded-graph-rewriter

Denys Petrov via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 22 03:44:37 PDT 2020


Author: Denys Petrov
Date: 2020-06-22T13:44:27+03:00
New Revision: 01f9388d95aca2cc86ed6b2794e199ef55d16e91

URL: https://github.com/llvm/llvm-project/commit/01f9388d95aca2cc86ed6b2794e199ef55d16e91
DIFF: https://github.com/llvm/llvm-project/commit/01f9388d95aca2cc86ed6b2794e199ef55d16e91.diff

LOG: [analyzer] Handle `\l` symbol in string literals in exploded-graph-rewriter

Summary:
Handle `\l` separately because a string literal can be in code like "string\\literal" with the `\l` inside. Also on Windows macros __FILE__ produces specific delimiters `\` and a directory or file may starts with the letter `l`.

Fix:
Use regex for replacing all `\l` (like `,\l`, `}\l`, `[\l`) except `\\l`, because a literal as a rule contains multiple `\` before `\l`.

Differential Revision: https://reviews.llvm.org/D82092

Added: 
    clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp

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

Removed: 
    


################################################################################
diff  --git a/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp b/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp
new file mode 100644
index 000000000000..b84c49974530
--- /dev/null
+++ b/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp
@@ -0,0 +1,28 @@
+// CAUTION: The name of this file should start with `l` for proper tests.
+// FIXME: Figure out how to use %clang_analyze_cc1 with our lit.local.cfg.
+// RUN: %clang_cc1 -analyze -triple x86_64-unknown-linux-gnu \
+// RUN:                     -analyzer-checker=core \
+// RUN:                     -analyzer-dump-egraph=%t.dot %s
+// RUN: %exploded_graph_rewriter %t.dot | FileCheck %s
+// REQUIRES: asserts
+
+void test1() {
+  // Here __FILE__ macros produces a string with `\` delimiters on Windows
+  // and the name of the file starts with `l`.
+  char text[] = __FILE__;
+}
+
+void test2() {
+  // Here `\l` is in the middle of the literal.
+  char text[] = "string\\literal";
+}
+
+void test() {
+  test1();
+  test2();
+}
+
+// This test is passed if exploded_graph_rewriter handles dot file without errors.
+// CHECK: digraph "ExplodedGraph"
+// CHECK: clang\\test\\Analysis\\exploded-graph-rewriter\\l_name_starts_with_l.cpp";
+// CHECK: char text[] = "string\\literal";

diff  --git a/clang/utils/analyzer/exploded-graph-rewriter.py b/clang/utils/analyzer/exploded-graph-rewriter.py
index bae863cb6d04..54d87addd3da 100755
--- a/clang/utils/analyzer/exploded-graph-rewriter.py
+++ b/clang/utils/analyzer/exploded-graph-rewriter.py
@@ -368,8 +368,7 @@ def add_raw_line(self, raw_line):
                 self.root_id = node_id
             # Note: when writing tests you don't need to escape everything,
             # even though in a valid dot file everything is escaped.
-            node_label = result.group(2).replace('\\l', '') \
-                                        .replace(' ', '') \
+            node_label = result.group(2).replace(' ', '') \
                                         .replace('\\"', '"') \
                                         .replace('\\{', '{') \
                                         .replace('\\}', '}') \
@@ -378,6 +377,13 @@ def add_raw_line(self, raw_line):
                                         .replace('\\<', '\\\\<') \
                                         .replace('\\>', '\\\\>') \
                                         .rstrip(',')
+            # Handle `\l` separately because a string literal can be in code
+            # like "string\\literal" with the `\l` inside.
+            # Also on Windows macros __FILE__ produces specific delimiters `\`
+            # and a directory or file may starts with the letter `l`.
+            # Find all `\l` (like `,\l`, `}\l`, `[\l`) except `\\l`,
+            # because the literal as a rule containes multiple `\` before `\l`.
+            node_label = re.sub(r'(?<!\\)\\l', '', node_label)
             logging.debug(node_label)
             json_node = json.loads(node_label)
             self.nodes[node_id].construct(node_id, json_node)
@@ -422,8 +428,8 @@ def _dump(self, s):
              .replace('}', '\\}') \
              .replace('\\<', '<') \
              .replace('\\>', '>') \
-             .replace('\\l', '<br />') \
              .replace('|', '\\|')
+        s = re.sub(r'(?<!\\)\\l', '<br />', s)
         if self._gray_mode:
             s = re.sub(r'<font color="[a-z0-9]*">', '', s)
             s = re.sub(r'</font>', '', s)


        


More information about the cfe-commits mailing list