summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-07-01 23:01:59 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-07-01 23:01:59 +0000
commitf21127243dbe044a67dbaf7361ba5aabefb1142c (patch)
treef76db8da0eb7939f553e58b471ab19b93c00abb4
parentd4916e2a6ffbff852897a807f87e4e83b1a2145c (diff)
downloadclang-f21127243dbe044a67dbaf7361ba5aabefb1142c.tar.gz
[analyzer] exploded-graph-rewriter: Add support for dynamic types.
Slightly cleanup emission of horizontal lines and unhardcode the title for generic maps. Differential Revision: https://reviews.llvm.org/D64041 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@364865 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/Analysis/exploded-graph-rewriter/constraints.dot1
-rw-r--r--test/Analysis/exploded-graph-rewriter/constraints_diff.dot5
-rw-r--r--test/Analysis/exploded-graph-rewriter/environment.dot1
-rw-r--r--test/Analysis/exploded-graph-rewriter/environment_diff.dot3
-rw-r--r--test/Analysis/exploded-graph-rewriter/store.dot1
-rw-r--r--test/Analysis/exploded-graph-rewriter/store_diff.dot2
-rwxr-xr-xutils/analyzer/exploded-graph-rewriter.py42
7 files changed, 37 insertions, 18 deletions
diff --git a/test/Analysis/exploded-graph-rewriter/constraints.dot b/test/Analysis/exploded-graph-rewriter/constraints.dot
index f9ffde7431..49aba4b15e 100644
--- a/test/Analysis/exploded-graph-rewriter/constraints.dot
+++ b/test/Analysis/exploded-graph-rewriter/constraints.dot
@@ -19,6 +19,7 @@ Node0x1 [shape=record,label=
"program_state": {
"store": null,
"environment": null,
+ "dynamic_types": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 0] }" }
]
diff --git a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
index a65a3a2464..068ef58d25 100644
--- a/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/constraints_diff.dot
@@ -12,6 +12,7 @@ Node0x1 [shape=record,label=
"program_state": {
"store": null,
"environment": null,
+ "dynamic_types": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 10] }" }
]
@@ -41,6 +42,7 @@ Node0x3 [shape=record,label=
"program_state": {
"store": null,
"environment": null,
+ "dynamic_types": null,
"constraints": [
{ "symbol": "reg_$0<x>", "range": "{ [0, 5] }" }
]
@@ -59,7 +61,8 @@ Node0x5 [shape=record,label=
"program_state": {
"store": null,
"environment": null,
- "constraints": null
+ "constraints": null,
+ "dynamic_types": null
}
}
\l}"];
diff --git a/test/Analysis/exploded-graph-rewriter/environment.dot b/test/Analysis/exploded-graph-rewriter/environment.dot
index f624975db6..4c6c93b85d 100644
--- a/test/Analysis/exploded-graph-rewriter/environment.dot
+++ b/test/Analysis/exploded-graph-rewriter/environment.dot
@@ -34,6 +34,7 @@ Node0x1 [shape=record,label=
"program_state": {
"store": null,
"constraints": null,
+ "dynamic_types": null,
"environment": {
"pointer": "0x2",
"items": [
diff --git a/test/Analysis/exploded-graph-rewriter/environment_diff.dot b/test/Analysis/exploded-graph-rewriter/environment_diff.dot
index 84f89dd469..ac41cdf97f 100644
--- a/test/Analysis/exploded-graph-rewriter/environment_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/environment_diff.dot
@@ -13,6 +13,7 @@ Node0x1 [shape=record,label=
"program_state": {
"store": null,
"constraints": null,
+ "dynamic_types": null,
"environment": {
"pointer": "0x2",
"items": [
@@ -59,6 +60,7 @@ Node0x6 [shape=record,label=
"program_state": {
"store": null,
"constraints": null,
+ "dynamic_types": null,
"environment": {
"pointer": "0x2",
"items": [
@@ -99,6 +101,7 @@ Node0x9 [shape=record,label=
"program_state": {
"store": null,
"constraints": null,
+ "dynamic_types": null,
"environment": {
"pointer": "0x2",
"items": [
diff --git a/test/Analysis/exploded-graph-rewriter/store.dot b/test/Analysis/exploded-graph-rewriter/store.dot
index 8f33b513b1..f431319cc6 100644
--- a/test/Analysis/exploded-graph-rewriter/store.dot
+++ b/test/Analysis/exploded-graph-rewriter/store.dot
@@ -29,6 +29,7 @@ Node0x1 [shape=record,label=
"program_state": {
"environment": null,
"constraints": null,
+ "dynamic_types": null,
"store": {
"pointer": "0x2",
"items": [
diff --git a/test/Analysis/exploded-graph-rewriter/store_diff.dot b/test/Analysis/exploded-graph-rewriter/store_diff.dot
index af92c62163..ab36e5f986 100644
--- a/test/Analysis/exploded-graph-rewriter/store_diff.dot
+++ b/test/Analysis/exploded-graph-rewriter/store_diff.dot
@@ -12,6 +12,7 @@ Node0x1 [shape=record,label=
"program_state": {
"environment": null,
"constraints": null,
+ "dynamic_types": null,
"store": {
"pointer": "0x2",
"items": [
@@ -57,6 +58,7 @@ Node0x4 [shape=record,label=
"program_state": {
"environment": null,
"constraints": null,
+ "dynamic_types": null,
"store": {
"pointer": "0x5",
"items": [
diff --git a/utils/analyzer/exploded-graph-rewriter.py b/utils/analyzer/exploded-graph-rewriter.py
index c4b015e5de..b033814ed9 100755
--- a/utils/analyzer/exploded-graph-rewriter.py
+++ b/utils/analyzer/exploded-graph-rewriter.py
@@ -27,8 +27,8 @@ def diff_dicts(curr, prev):
# Represents any program state trait that is a dictionary of key-value pairs.
class GenericMap(object):
- def __init__(self, generic_map):
- self.generic_map = generic_map
+ def __init__(self, items):
+ self.generic_map = collections.OrderedDict(items)
def diff(self, prev):
return diff_dicts(self.generic_map, prev.generic_map)
@@ -218,11 +218,17 @@ class ProgramState(object):
if json_ps['store'] is not None else None
self.environment = Environment(json_ps['environment']) \
if json_ps['environment'] is not None else None
- self.constraints = GenericMap(collections.OrderedDict([
+ self.constraints = GenericMap([
(c['symbol'], c['range']) for c in json_ps['constraints']
- ])) if json_ps['constraints'] is not None else None
+ ]) if json_ps['constraints'] is not None else None
+ self.dynamic_types = GenericMap([
+ (t['region'], '%s%s' % (t['dyn_type'],
+ ' (or a sub-class)'
+ if t['sub_classable'] else ''))
+ for t in json_ps['dynamic_types']]) \
+ if json_ps['dynamic_types'] is not None else None
+
# TODO: Objects under construction.
- # TODO: Dynamic types of objects.
# TODO: Checker messages.
@@ -435,8 +441,7 @@ class DotDumpVisitor(object):
self._dump('</table>')
def visit_environment_in_state(self, s, prev_s=None):
- self._dump('<tr><td align="left">'
- '<b>Environment: </b>')
+ self._dump('<hr /><tr><td align="left"><b>Environment: </b>')
if s.environment is None:
self._dump('<i> Nothing!</i>')
else:
@@ -491,7 +496,7 @@ class DotDumpVisitor(object):
self._dump('</table>')
def visit_store_in_state(self, s, prev_s=None):
- self._dump('<tr><td align="left"><b>Store: </b>')
+ self._dump('<hr /><tr><td align="left"><b>Store: </b>')
if s.store is None:
self._dump('<i> Nothing!</i>')
else:
@@ -528,16 +533,19 @@ class DotDumpVisitor(object):
self._dump('</table>')
- def visit_generic_map_in_state(self, selector, s, prev_s=None):
- self._dump('<tr><td align="left">'
- '<b>Ranges: </b>')
+ def visit_generic_map_in_state(self, selector, title, s, prev_s=None):
m = getattr(s, selector)
+ prev_m = getattr(prev_s, selector) if prev_s is not None else None
+ if m is None and prev_m is None:
+ return
+
+ self._dump('<hr />')
+ self._dump('<tr><td align="left">'
+ '<b>%s: </b>' % title)
if m is None:
self._dump('<i> Nothing!</i>')
else:
- prev_m = None
if prev_s is not None:
- prev_m = getattr(prev_s, selector)
if prev_m is not None:
if m.is_different(prev_m):
self._dump('</td></tr><tr><td align="left">')
@@ -551,10 +559,11 @@ class DotDumpVisitor(object):
def visit_state(self, s, prev_s):
self.visit_store_in_state(s, prev_s)
- self._dump('<hr />')
self.visit_environment_in_state(s, prev_s)
- self._dump('<hr />')
- self.visit_generic_map_in_state('constraints', 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)
def visit_node(self, node):
self._dump('%s [shape=record,label=<<table border="0">'
@@ -576,7 +585,6 @@ class DotDumpVisitor(object):
self._dump('</table></td></tr>')
if node.state is not None:
- self._dump('<hr />')
prev_s = None
# Do diffs only when we have a unique predecessor.
# Don't do diffs on the leaf nodes because they're