r364880 - [analyzer] exploded-graph-rewriter: Add support for objects under construction.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 1 19:17:51 PDT 2019
Author: dergachev
Date: Mon Jul 1 19:17:50 2019
New Revision: 364880
URL: http://llvm.org/viewvc/llvm-project?rev=364880&view=rev
Log:
[analyzer] exploded-graph-rewriter: Add support for objects under construction.
This trait is Environment-like, so there was a chance to re-use a lot of code.
Differential Revision: https://reviews.llvm.org/D64047
Added:
cfe/trunk/test/Analysis/exploded-graph-rewriter/initializers_under_construction.cpp
cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp
Modified:
cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot
cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot
cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot
cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot
cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot
cfe/trunk/utils/analyzer/exploded-graph-rewriter.py
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints.dot Mon Jul 1 19:17:50 2019
@@ -20,6 +20,7 @@ Node0x1 [shape=record,label=
"store": null,
"environment": null,
"dynamic_types": null,
+ "constructing_objects": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 0] }" }
]
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/constraints_diff.dot Mon Jul 1 19:17:50 2019
@@ -13,6 +13,7 @@ Node0x1 [shape=record,label=
"store": null,
"environment": null,
"dynamic_types": null,
+ "constructing_objects": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 10] }" }
]
@@ -43,6 +44,7 @@ Node0x3 [shape=record,label=
"store": null,
"environment": null,
"dynamic_types": null,
+ "constructing_objects": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 5] }" }
]
@@ -62,7 +64,8 @@ Node0x5 [shape=record,label=
"store": null,
"environment": null,
"constraints": null,
- "dynamic_types": null
+ "dynamic_types": null,
+ "constructing_objects": null
}
}
\l}"];
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/environment.dot Mon Jul 1 19:17:50 2019
@@ -35,6 +35,7 @@ Node0x1 [shape=record,label=
"store": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"environment": {
"pointer": "0x2",
"items": [
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/environment_diff.dot Mon Jul 1 19:17:50 2019
@@ -14,6 +14,7 @@ Node0x1 [shape=record,label=
"store": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"environment": {
"pointer": "0x2",
"items": [
@@ -61,6 +62,7 @@ Node0x6 [shape=record,label=
"store": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"environment": {
"pointer": "0x2",
"items": [
@@ -102,6 +104,7 @@ Node0x9 [shape=record,label=
"store": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"environment": {
"pointer": "0x2",
"items": [
Added: cfe/trunk/test/Analysis/exploded-graph-rewriter/initializers_under_construction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/initializers_under_construction.cpp?rev=364880&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/initializers_under_construction.cpp (added)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/initializers_under_construction.cpp Mon Jul 1 19:17:50 2019
@@ -0,0 +1,25 @@
+// 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
+
+// FIXME: Substitution doesn't seem to work on Windows.
+// UNSUPPORTED: system-windows
+
+struct A {
+ A() {}
+};
+
+struct B {
+ A a;
+ B() : a() {}
+};
+
+void test() {
+ // CHECK: (construct into member variable)
+ // CHECK-SAME: <td align="left">a</td>
+ // CHECK-SAME: <td align="left">&b->a</td>
+ B b;
+}
Added: cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp?rev=364880&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp (added)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp Mon Jul 1 19:17:50 2019
@@ -0,0 +1,48 @@
+// 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
+
+// FIXME: Substitution doesn't seem to work on Windows.
+// UNSUPPORTED: system-windows
+
+struct S {
+ S() {}
+};
+
+void test() {
+ // CHECK: Objects Under Construction:
+ // CHECK-SAME: <tr>
+ // CHECK-SAME: <td align="left"><b>#0 Call</b></td>
+ // CHECK-SAME: <td align="left" colspan="2">
+ // CHECK-SAME: <font color="grey60">test </font>
+ // CHECK-SAME: </td>
+ // CHECK-SAME: </tr>
+ // CHECK-SAME: <tr>
+ // CHECK-SAME: <td align="left"><i>S{{[0-9]*}}</i></td>
+ // CHECK-SAME: <td align="left"><font color="darkgreen"><i>
+ // CHECK-SAME: (materialize temporary)
+ // CHECK-SAME: </i></font></td>
+ // CHECK-SAME: <td align="left">S()</td>
+ // CHECK-SAME: <td align="left">&s</td>
+ // CHECK-SAME: </tr>
+ // CHECK-SAME: <tr>
+ // CHECK-SAME: <td align="left"><i>S{{[0-9]*}}</i></td>
+ // CHECK-SAME: <td align="left"><font color="darkgreen"><i>
+ // CHECK-SAME: (elide constructor)
+ // CHECK-SAME: </i></font></td>
+ // CHECK-SAME: <td align="left">S()</td>
+ // CHECK-SAME: <td align="left">&s</td>
+ // CHECK-SAME: </tr>
+ // CHECK-SAME: <tr>
+ // CHECK-SAME: <td align="left"><i>S{{[0-9]*}}</i></td>
+ // CHECK-SAME: <td align="left"><font color="darkgreen"><i>
+ // CHECK-SAME: (construct into local variable)
+ // CHECK-SAME: </i></font></td>
+ // CHECK-SAME: <td align="left">S s = S();</td>
+ // CHECK-SAME: <td align="left">&s</td>
+ // CHECK-SAME: </tr>
+ S s = S();
+}
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/store.dot Mon Jul 1 19:17:50 2019
@@ -30,6 +30,7 @@ Node0x1 [shape=record,label=
"environment": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"store": {
"pointer": "0x2",
"items": [
Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/store_diff.dot Mon Jul 1 19:17:50 2019
@@ -13,6 +13,7 @@ Node0x1 [shape=record,label=
"environment": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"store": {
"pointer": "0x2",
"items": [
@@ -59,6 +60,7 @@ Node0x4 [shape=record,label=
"environment": null,
"constraints": null,
"dynamic_types": null,
+ "constructing_objects": null,
"store": {
"pointer": "0x5",
"items": [
Modified: cfe/trunk/utils/analyzer/exploded-graph-rewriter.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/exploded-graph-rewriter.py?rev=364880&r1=364879&r2=364880&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/exploded-graph-rewriter.py (original)
+++ cfe/trunk/utils/analyzer/exploded-graph-rewriter.py Mon Jul 1 19:17:50 2019
@@ -71,8 +71,11 @@ class ProgramPoint(object):
class EnvironmentBindingKey(object):
def __init__(self, json_ek):
super(EnvironmentBindingKey, self).__init__()
- self.stmt_id = json_ek['stmt_id']
+ # CXXCtorInitializer is not a Stmt!
+ self.stmt_id = json_ek['stmt_id'] if 'stmt_id' in json_ek \
+ else json_ek['init_id']
self.pretty = json_ek['pretty']
+ self.kind = json_ek['kind'] if 'kind' in json_ek else None
def _key(self):
return self.stmt_id
@@ -122,12 +125,12 @@ class EnvironmentFrame(object):
return len(removed) != 0 or len(added) != 0
-# A deserialized Environment.
-class Environment(object):
+# A deserialized Environment. This class can also hold other entities that
+# are similar to Environment, such as Objects Under Construction.
+class GenericEnvironment(object):
def __init__(self, json_e):
- super(Environment, self).__init__()
- self.ptr = json_e['pointer']
- self.frames = [EnvironmentFrame(f) for f in json_e['items']]
+ super(GenericEnvironment, self).__init__()
+ self.frames = [EnvironmentFrame(f) for f in json_e]
def diff_frames(self, prev):
# TODO: It's difficult to display a good diff when frame numbers shift.
@@ -214,13 +217,18 @@ class ProgramState(object):
logging.debug('Adding ProgramState ' + str(state_id))
self.state_id = state_id
+
self.store = Store(json_ps['store']) \
if json_ps['store'] is not None else None
- self.environment = Environment(json_ps['environment']) \
+
+ self.environment = \
+ GenericEnvironment(json_ps['environment']['items']) \
if json_ps['environment'] is not None else None
+
self.constraints = GenericMap([
(c['symbol'], c['range']) for c in json_ps['constraints']
]) if json_ps['constraints'] is not None else None
+
self.dynamic_types = GenericMap([
(t['region'], '%s%s' % (t['dyn_type'],
' (or a sub-class)'
@@ -228,7 +236,10 @@ class ProgramState(object):
for t in json_ps['dynamic_types']]) \
if json_ps['dynamic_types'] is not None else None
- # TODO: Objects under construction.
+ self.constructing_objects = \
+ GenericEnvironment(json_ps['constructing_objects']) \
+ if json_ps['constructing_objects'] is not None else None
+
# TODO: Checker messages.
@@ -416,10 +427,15 @@ class DotDumpVisitor(object):
def dump_binding(f, b, is_added=None):
self._dump('<tr><td>%s</td>'
'<td align="left"><i>S%s</i></td>'
+ '%s'
'<td align="left">%s</td>'
'<td align="left">%s</td></tr>'
% (self._diff_plus_minus(is_added),
- b.stmt_id, b.pretty, f.bindings[b]))
+ b.stmt_id,
+ '<td align="left"><font color="darkgreen"><i>'
+ '(%s)</i></font></td>' % b.kind
+ if b.kind is not None else '',
+ b.pretty, f.bindings[b]))
frames_updated = e.diff_frames(prev_e) if prev_e is not None else None
if frames_updated:
@@ -440,20 +456,25 @@ class DotDumpVisitor(object):
self._dump('</table>')
- def visit_environment_in_state(self, s, prev_s=None):
- self._dump('<hr /><tr><td align="left"><b>Environment: </b>')
- if s.environment is None:
+ def visit_environment_in_state(self, selector, title, s, prev_s=None):
+ e = getattr(s, selector)
+ prev_e = getattr(prev_s, selector) if prev_s is not None else None
+ if e is None and prev_e is None:
+ return
+
+ self._dump('<hr /><tr><td align="left"><b>%s: </b>' % title)
+ if e is None:
self._dump('<i> Nothing!</i>')
else:
- if prev_s is not None and prev_s.environment is not None:
- if s.environment.is_different(prev_s.environment):
+ if prev_e is not None:
+ if e.is_different(prev_e):
self._dump('</td></tr><tr><td align="left">')
- self.visit_environment(s.environment, prev_s.environment)
+ self.visit_environment(e, prev_e)
else:
self._dump('<i> No changes!</i>')
else:
self._dump('</td></tr><tr><td align="left">')
- self.visit_environment(s.environment)
+ self.visit_environment(e)
self._dump('</td></tr>')
@@ -496,19 +517,24 @@ class DotDumpVisitor(object):
self._dump('</table>')
def visit_store_in_state(self, s, prev_s=None):
+ st = s.store
+ prev_st = prev_s.store if prev_s is not None else None
+ if st is None and prev_st is None:
+ return
+
self._dump('<hr /><tr><td align="left"><b>Store: </b>')
- if s.store is None:
+ if st is None:
self._dump('<i> Nothing!</i>')
else:
- if prev_s is not None and prev_s.store is not None:
- if s.store.is_different(prev_s.store):
+ if prev_st is not None:
+ if s.store.is_different(prev_st):
self._dump('</td></tr><tr><td align="left">')
- self.visit_store(s.store, prev_s.store)
+ self.visit_store(st, prev_st)
else:
self._dump('<i> No changes!</i>')
else:
self._dump('</td></tr><tr><td align="left">')
- self.visit_store(s.store)
+ self.visit_store(st)
self._dump('</td></tr>')
def visit_generic_map(self, m, prev_m=None):
@@ -559,11 +585,15 @@ class DotDumpVisitor(object):
def visit_state(self, s, prev_s):
self.visit_store_in_state(s, prev_s)
- self.visit_environment_in_state(s, prev_s)
+ self.visit_environment_in_state('environment', 'Environment',
+ s, prev_s)
self.visit_generic_map_in_state('constraints', 'Ranges',
s, prev_s)
self.visit_generic_map_in_state('dynamic_types', 'Dynamic Types',
s, prev_s)
+ self.visit_environment_in_state('constructing_objects',
+ 'Objects Under Construction',
+ s, prev_s)
def visit_node(self, node):
self._dump('%s [shape=record,label=<<table border="0">'
More information about the cfe-commits
mailing list