From 02f91ddf1b353b28697b288edbe6a8a828705781 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Mon, 1 Jul 2019 23:01:59 +0000 Subject: [PATCH] [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 llvm-svn: 364865 --- .../exploded-graph-rewriter/constraints.dot | 1 + .../exploded-graph-rewriter/constraints_diff.dot | 5 ++- .../exploded-graph-rewriter/environment.dot | 1 + .../exploded-graph-rewriter/environment_diff.dot | 3 ++ .../Analysis/exploded-graph-rewriter/store.dot | 1 + .../exploded-graph-rewriter/store_diff.dot | 2 ++ clang/utils/analyzer/exploded-graph-rewriter.py | 42 +++++++++++++--------- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/clang/test/Analysis/exploded-graph-rewriter/constraints.dot b/clang/test/Analysis/exploded-graph-rewriter/constraints.dot index f9ffde7..49aba4b 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/constraints.dot +++ b/clang/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", "range": "{ [0, 0] }" } ] diff --git a/clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot b/clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot index a65a3a2..068ef58 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/constraints_diff.dot +++ b/clang/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", "range": "{ [0, 10] }" } ] @@ -41,6 +42,7 @@ Node0x3 [shape=record,label= "program_state": { "store": null, "environment": null, + "dynamic_types": null, "constraints": [ { "symbol": "reg_$0", "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/clang/test/Analysis/exploded-graph-rewriter/environment.dot b/clang/test/Analysis/exploded-graph-rewriter/environment.dot index f624975..4c6c93b 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/environment.dot +++ b/clang/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/clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot b/clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot index 84f89dd..ac41cdf 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/environment_diff.dot +++ b/clang/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/clang/test/Analysis/exploded-graph-rewriter/store.dot b/clang/test/Analysis/exploded-graph-rewriter/store.dot index 8f33b51..f431319 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/store.dot +++ b/clang/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/clang/test/Analysis/exploded-graph-rewriter/store_diff.dot b/clang/test/Analysis/exploded-graph-rewriter/store_diff.dot index af92c62..ab36e5f 100644 --- a/clang/test/Analysis/exploded-graph-rewriter/store_diff.dot +++ b/clang/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/clang/utils/analyzer/exploded-graph-rewriter.py b/clang/utils/analyzer/exploded-graph-rewriter.py index c4b015e..b033814 100755 --- a/clang/utils/analyzer/exploded-graph-rewriter.py +++ b/clang/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('') def visit_environment_in_state(self, s, prev_s=None): - self._dump('' - 'Environment: ') + self._dump('
Environment: ') if s.environment is None: self._dump(' Nothing!') else: @@ -491,7 +496,7 @@ class DotDumpVisitor(object): self._dump('') def visit_store_in_state(self, s, prev_s=None): - self._dump('Store: ') + self._dump('
Store: ') if s.store is None: self._dump(' Nothing!') else: @@ -528,16 +533,19 @@ class DotDumpVisitor(object): self._dump('') - def visit_generic_map_in_state(self, selector, s, prev_s=None): - self._dump('' - 'Ranges: ') + 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('
') + self._dump('' + '%s: ' % title) if m is None: self._dump(' Nothing!') 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('') @@ -551,10 +559,11 @@ class DotDumpVisitor(object): def visit_state(self, s, prev_s): self.visit_store_in_state(s, prev_s) - self._dump('
') self.visit_environment_in_state(s, prev_s) - self._dump('
') - 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=<' @@ -576,7 +585,6 @@ class DotDumpVisitor(object): self._dump('
') if node.state is not None: - self._dump('
') prev_s = None # Do diffs only when we have a unique predecessor. # Don't do diffs on the leaf nodes because they're -- 2.7.4