[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
This commit is contained in:
Denys Petrov 2020-06-22 13:11:54 +03:00
parent 6cb80fbe40
commit 01f9388d95
2 changed files with 37 additions and 3 deletions

View File

@ -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";

View File

@ -368,8 +368,7 @@ class ExplodedGraph:
self.root_id = node_id self.root_id = node_id
# Note: when writing tests you don't need to escape everything, # Note: when writing tests you don't need to escape everything,
# even though in a valid dot file everything is escaped. # even though in a valid dot file everything is escaped.
node_label = result.group(2).replace('\\l', '') \ node_label = result.group(2).replace(' ', '') \
.replace(' ', '') \
.replace('\\"', '"') \ .replace('\\"', '"') \
.replace('\\{', '{') \ .replace('\\{', '{') \
.replace('\\}', '}') \ .replace('\\}', '}') \
@ -378,6 +377,13 @@ class ExplodedGraph:
.replace('\\<', '\\\\<') \ .replace('\\<', '\\\\<') \
.replace('\\>', '\\\\>') \ .replace('\\>', '\\\\>') \
.rstrip(',') .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) logging.debug(node_label)
json_node = json.loads(node_label) json_node = json.loads(node_label)
self.nodes[node_id].construct(node_id, json_node) self.nodes[node_id].construct(node_id, json_node)
@ -422,8 +428,8 @@ class DotDumpVisitor:
.replace('}', '\\}') \ .replace('}', '\\}') \
.replace('\\<', '&lt;') \ .replace('\\<', '&lt;') \
.replace('\\>', '&gt;') \ .replace('\\>', '&gt;') \
.replace('\\l', '<br />') \
.replace('|', '\\|') .replace('|', '\\|')
s = re.sub(r'(?<!\\)\\l', '<br />', s)
if self._gray_mode: if self._gray_mode:
s = re.sub(r'<font color="[a-z0-9]*">', '', s) s = re.sub(r'<font color="[a-z0-9]*">', '', s)
s = re.sub(r'</font>', '', s) s = re.sub(r'</font>', '', s)