annotate gcc/analyzer/region-model.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* Classes for modeling the state of memory.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #ifndef GCC_ANALYZER_REGION_MODEL_H
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #define GCC_ANALYZER_REGION_MODEL_H
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 /* Implementation of the region-based ternary model described in:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 "A Memory Model for Static Analysis of C Programs"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 (Zhongxing Xu, Ted Kremenek, and Jian Zhang)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 /* A tree, extended with stack frame information for locals, so that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 we can distinguish between different values of locals within a potentially
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 recursive callstack. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 // TODO: would this be better as a new tree code?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 using namespace ana;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 class path_var
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 path_var (tree t, int stack_depth)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 : m_tree (t), m_stack_depth (stack_depth)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 // TODO: ignore stack depth for globals and constants
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 bool operator== (const path_var &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 return (m_tree == other.m_tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 && m_stack_depth == other.m_stack_depth);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 void dump (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 tree m_tree;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 int m_stack_depth; // or -1 for globals?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 namespace inchash
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 extern void add_path_var (path_var pv, hash &hstate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 } // namespace inchash
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 /* A region_model is effectively a graph of regions and symbolic values.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 We store per-model IDs rather than pointers to make it easier to clone
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 and to compare graphs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 /* An ID for an svalue within a region_model. Internally, this is an index
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 into a vector of svalue * within the region_model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 class svalue_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 static svalue_id null () { return svalue_id (-1); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 svalue_id () : m_idx (-1) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 bool operator== (const svalue_id &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 return m_idx == other.m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 bool operator!= (const svalue_id &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 return m_idx != other.m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 bool null_p () const { return m_idx == -1; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 static svalue_id from_int (int idx) { return svalue_id (idx); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 int as_int () const { return m_idx; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 void print (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 void dump_node_name_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 void validate (const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 svalue_id (int idx) : m_idx (idx) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 int m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 /* An ID for a region within a region_model. Internally, this is an index
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 into a vector of region * within the region_model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 class region_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 static region_id null () { return region_id (-1); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 region_id () : m_idx (-1) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 bool operator== (const region_id &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 return m_idx == other.m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 bool operator!= (const region_id &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 return m_idx != other.m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 bool null_p () const { return m_idx == -1; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 static region_id from_int (int idx) { return region_id (idx); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 int as_int () const { return m_idx; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 void print (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 void dump_node_name_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 void validate (const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 region_id (int idx) : m_idx (idx) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 int m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 /* A class for renumbering IDs within a region_model, mapping old IDs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 to new IDs (e.g. when removing one or more elements, thus needing to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 renumber). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 // TODO: could this be useful for equiv_class_ids?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 class id_map
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 id_map (int num_ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 void put (T src, T dst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 T get_dst_for_src (T src) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 T get_src_for_dst (T dst) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 void dump_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 void dump () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 void update (T *) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 auto_vec<T> m_src_to_dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 auto_vec<T> m_dst_to_src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 typedef id_map<svalue_id> svalue_id_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 typedef id_map<region_id> region_id_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 /* class id_map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 /* id_map's ctor, which populates the map with dummy null values. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 inline id_map<T>::id_map (int num_svalues)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 : m_src_to_dst (num_svalues),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 m_dst_to_src (num_svalues)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 for (int i = 0; i < num_svalues; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 m_src_to_dst.quick_push (T::null ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 m_dst_to_src.quick_push (T::null ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 /* Record that SRC is to be mapped to DST. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 id_map<T>::put (T src, T dst)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 m_src_to_dst[src.as_int ()] = dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 m_dst_to_src[dst.as_int ()] = src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 /* Get the new value for SRC within the map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 inline T
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 id_map<T>::get_dst_for_src (T src) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 if (src.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 return src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 return m_src_to_dst[src.as_int ()];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 /* Given DST, a new value, determine which old value will be mapped to it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 (the inverse of the map). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 inline T
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 id_map<T>::get_src_for_dst (T dst) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 if (dst.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 return dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 return m_dst_to_src[dst.as_int ()];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 /* Dump this id_map to PP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 id_map<T>::dump_to_pp (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 pp_string (pp, "src to dst: {");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 unsigned i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 T *dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 FOR_EACH_VEC_ELT (m_src_to_dst, i, dst)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 pp_string (pp, ", ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 T src (T::from_int (i));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 src.print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 pp_string (pp, " -> ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 dst->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 pp_string (pp, "}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 pp_string (pp, "dst to src: {");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 T *src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 FOR_EACH_VEC_ELT (m_dst_to_src, i, src)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 pp_string (pp, ", ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 T dst (T::from_int (i));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 dst.print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 pp_string (pp, " <- ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 src->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 pp_string (pp, "}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 /* Dump this id_map to stderr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 DEBUG_FUNCTION inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 id_map<T>::dump () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 pretty_printer pp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 pp.buffer->stream = stderr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 dump_to_pp (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 pp_flush (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 /* Update *ID from the old value to its new value in this map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 id_map<T>::update (T *id) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 *id = get_dst_for_src (*id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 /* Variant of the above, which only stores things in one direction.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 (e.g. for merging, when the number of destination regions is not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 the same of the src regions, and can grow). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 class one_way_id_map
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 one_way_id_map (int num_ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 void put (T src, T dst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 T get_dst_for_src (T src) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 void dump_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 void dump () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 void update (T *) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 auto_vec<T> m_src_to_dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 typedef one_way_id_map<svalue_id> one_way_svalue_id_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 typedef one_way_id_map<region_id> one_way_region_id_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 /* class one_way_id_map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 /* one_way_id_map's ctor, which populates the map with dummy null values. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 inline one_way_id_map<T>::one_way_id_map (int num_svalues)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 : m_src_to_dst (num_svalues)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 for (int i = 0; i < num_svalues; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 m_src_to_dst.quick_push (T::null ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 /* Record that SRC is to be mapped to DST. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 one_way_id_map<T>::put (T src, T dst)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 m_src_to_dst[src.as_int ()] = dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 /* Get the new value for SRC within the map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 inline T
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 one_way_id_map<T>::get_dst_for_src (T src) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 if (src.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 return src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 return m_src_to_dst[src.as_int ()];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 /* Dump this map to PP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 one_way_id_map<T>::dump_to_pp (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 pp_string (pp, "src to dst: {");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 unsigned i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 T *dst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 FOR_EACH_VEC_ELT (m_src_to_dst, i, dst)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 pp_string (pp, ", ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 T src (T::from_int (i));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 src.print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 pp_string (pp, " -> ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 dst->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 pp_string (pp, "}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 /* Dump this map to stderr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 DEBUG_FUNCTION inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 one_way_id_map<T>::dump () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 pretty_printer pp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 pp.buffer->stream = stderr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 dump_to_pp (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 pp_flush (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 /* Update *ID from the old value to its new value in this map. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 inline void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 one_way_id_map<T>::update (T *id) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 *id = get_dst_for_src (*id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 /* A set of IDs within a region_model (either svalue_id or region_id). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 template <typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 class id_set
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 id_set (const region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 void add_region (T id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 if (!id.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 bitmap_set_bit (m_bitmap, id.as_int ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 bool region_p (T id) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 gcc_assert (!id.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 return bitmap_bit_p (const_cast <auto_sbitmap &> (m_bitmap),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 id.as_int ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 unsigned int num_regions ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 return bitmap_count_bits (m_bitmap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 auto_sbitmap m_bitmap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 typedef id_set<region_id> region_id_set;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 /* Various operations delete information from a region_model.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 This struct tracks how many of each kind of entity were purged (e.g.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 for selftests, and for debugging). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 struct purge_stats
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 purge_stats ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 : m_num_svalues (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 m_num_regions (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 m_num_equiv_classes (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 m_num_constraints (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 m_num_client_items (0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 int m_num_svalues;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 int m_num_regions;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 int m_num_equiv_classes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 int m_num_constraints;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 int m_num_client_items;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 /* An enum for discriminating between the different concrete subclasses
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 of svalue. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 enum svalue_kind
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 SK_REGION,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 SK_CONSTANT,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 SK_UNKNOWN,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 SK_POISONED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 SK_SETJMP
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 /* svalue and its subclasses.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 The class hierarchy looks like this (using indentation to show
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 inheritance, and with svalue_kinds shown for the concrete subclasses):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 region_svalue (SK_REGION)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 constant_svalue (SK_CONSTANT)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 unknown_svalue (SK_UNKNOWN)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 poisoned_svalue (SK_POISONED)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 setjmp_svalue (SK_SETJMP). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 /* An abstract base class representing a value held by a region of memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 class svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 virtual ~svalue () {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 bool operator== (const svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 bool operator!= (const svalue &other) const { return !(*this == other); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 virtual svalue *clone () const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 tree get_type () const { return m_type; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 virtual enum svalue_kind get_kind () const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 hashval_t hash () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 void print (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 virtual void dump_dot_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 virtual region_svalue *dyn_cast_region_svalue () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 virtual constant_svalue *dyn_cast_constant_svalue () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 virtual const constant_svalue *dyn_cast_constant_svalue () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 virtual poisoned_svalue *dyn_cast_poisoned_svalue () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 virtual unknown_svalue *dyn_cast_unknown_svalue () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 virtual setjmp_svalue *dyn_cast_setjmp_svalue () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 virtual void remap_region_ids (const region_id_map &map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 virtual void walk_for_canonicalization (canonicalization *c) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 virtual svalue_id get_child_sid (region *parent, region *child,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 tree maybe_get_constant () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 protected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 svalue (tree type) : m_type (type) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 virtual void add_to_hash (inchash::hash &hstate) const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 virtual void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 pretty_printer *pp) const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 tree m_type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 /* Concrete subclass of svalue representing a pointer value that points to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 a known region */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 class region_svalue : public svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 region_svalue (tree type, region_id rid) : svalue (type), m_rid (rid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 /* Should we support NULL ptrs here? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 gcc_assert (!rid.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 bool compare_fields (const region_svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 svalue *clone () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 { return new region_svalue (get_type (), m_rid); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_REGION; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 void dump_dot_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 region_svalue *dyn_cast_region_svalue () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 region_id get_pointee () const { return m_rid; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 void remap_region_ids (const region_id_map &map) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 static void merge_values (const region_svalue &region_sval_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 const region_svalue &region_sval_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 svalue_id *merged_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 tree type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 static tristate eval_condition (region_svalue *lhs_ptr,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 region_svalue *rhs_ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 region_id m_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 is_a_helper <region_svalue *>::test (svalue *sval)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 return sval->get_kind () == SK_REGION;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 /* Concrete subclass of svalue representing a specific constant value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 class constant_svalue : public svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 constant_svalue (tree cst_expr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 : svalue (TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 gcc_assert (cst_expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 gcc_assert (CONSTANT_CLASS_P (cst_expr));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 bool compare_fields (const constant_svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 svalue *clone () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 { return new constant_svalue (m_cst_expr); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_CONSTANT; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 constant_svalue *dyn_cast_constant_svalue () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 const constant_svalue *dyn_cast_constant_svalue () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 tree get_constant () const { return m_cst_expr; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 static void merge_values (const constant_svalue &cst_sval_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 const constant_svalue &cst_sval_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 svalue_id *merged_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 static tristate eval_condition (constant_svalue *lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 constant_svalue *rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 svalue_id get_child_sid (region *parent, region *child,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 region_model_context *ctxt) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 tree m_cst_expr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 is_a_helper <constant_svalue *>::test (svalue *sval)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 return sval->get_kind () == SK_CONSTANT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 /* Concrete subclass of svalue representing a unique but unknown value.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 Comparisons of variables that share the same unknown value are known
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 to be equal, even if we don't know what the value is. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 class unknown_svalue : public svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 unknown_svalue (tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 : svalue (type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 bool compare_fields (const unknown_svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 svalue *clone () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 { return new unknown_svalue (get_type ()); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_UNKNOWN; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 unknown_svalue *dyn_cast_unknown_svalue () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 /* An enum describing a particular kind of "poisoned" value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 enum poison_kind
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 /* For use to describe uninitialized memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 POISON_KIND_UNINIT,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 /* For use to describe freed memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 POISON_KIND_FREED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 /* For use on pointers to regions within popped stack frames. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 POISON_KIND_POPPED_STACK
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 extern const char *poison_kind_to_str (enum poison_kind);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 /* Concrete subclass of svalue representing a value that should not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 be used (e.g. uninitialized memory, freed memory). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 class poisoned_svalue : public svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 poisoned_svalue (enum poison_kind kind, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 : svalue (type), m_kind (kind) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 bool compare_fields (const poisoned_svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 svalue *clone () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 { return new poisoned_svalue (m_kind, get_type ()); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_POISONED; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 poisoned_svalue *dyn_cast_poisoned_svalue () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 enum poison_kind get_poison_kind () const { return m_kind; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 enum poison_kind m_kind;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 is_a_helper <poisoned_svalue *>::test (svalue *sval)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 return sval->get_kind () == SK_POISONED;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 /* A bundle of information recording a setjmp/sigsetjmp call, corresponding
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 roughly to a jmp_buf. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 struct setjmp_record
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 setjmp_record (const exploded_node *enode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 const gcall *setjmp_call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 : m_enode (enode), m_setjmp_call (setjmp_call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 bool operator== (const setjmp_record &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 return (m_enode == other.m_enode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 && m_setjmp_call == other.m_setjmp_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 const exploded_node *m_enode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 const gcall *m_setjmp_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 /* Concrete subclass of svalue representing buffers for setjmp/sigsetjmp,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 so that longjmp/siglongjmp can potentially "return" to an entirely
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 different function. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 class setjmp_svalue : public svalue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 setjmp_svalue (const setjmp_record &setjmp_record,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 : svalue (type), m_setjmp_record (setjmp_record)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 bool compare_fields (const setjmp_svalue &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 svalue *clone () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 { return new setjmp_svalue (m_setjmp_record, get_type ()); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_SETJMP; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 setjmp_svalue *dyn_cast_setjmp_svalue () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 int get_enode_index () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 const setjmp_record &get_setjmp_record () const { return m_setjmp_record; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 void print_details (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 svalue_id this_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 setjmp_record m_setjmp_record;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 /* An enum for discriminating between the different concrete subclasses
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 of region. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 enum region_kind
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 RK_PRIMITIVE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 RK_STRUCT,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 RK_UNION,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 RK_FRAME,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 RK_GLOBALS,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 RK_CODE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 RK_FUNCTION,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 RK_ARRAY,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 RK_STACK,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 RK_HEAP,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 RK_ROOT,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 RK_SYMBOLIC
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 extern const char *region_kind_to_str (enum region_kind);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 /* Region and its subclasses.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 The class hierarchy looks like this (using indentation to show
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 inheritance, and with region_kinds shown for the concrete subclasses):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 primitive_region (RK_PRIMITIVE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 map_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 struct_or_union_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 struct_region (RK_STRUCT)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 union_region (RK_UNION)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 scope_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 frame_region (RK_FRAME)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 globals_region (RK_GLOBALS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 code_region (RK_CODE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 function_region (RK_FUNCTION)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 array_region (RK_ARRAY)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 stack_region (RK_STACK)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 heap_region (RK_HEAP)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 root_region (RK_ROOT)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 label_region (RK_FUNCTION)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 symbolic_region (RK_SYMBOLIC). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 /* Abstract base class representing a chunk of memory.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 Regions form a tree-like hierarchy, with a root region at the base,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 with memory space regions within it, representing the stack and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 globals, with frames within the stack, and regions for variables
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 within the frames and the "globals" region. Regions for structs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 can have subregions for fields.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 A region can optionally have a value, or inherit its value from
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 the first ancestor with a value. For example, the stack region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 has a "uninitialized" poison value which is inherited by all
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 descendent regions that don't themselves have a value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 class region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 virtual ~region () {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 bool operator== (const region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 bool operator!= (const region &other) const { return !(*this == other); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 virtual region *clone () const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 virtual enum region_kind get_kind () const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 virtual map_region *dyn_cast_map_region () { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 virtual const symbolic_region *dyn_cast_symbolic_region () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 region_id get_parent () const { return m_parent_rid; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 region *get_parent_region (const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 void set_value (region_model &model, region_id this_rid, svalue_id rhs_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 svalue_id get_value (region_model &model, bool non_null,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 svalue_id get_value_direct () const { return m_sval_id; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 svalue_id get_inherited_child_sid (region *child,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 tree get_type () const { return m_type; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 hashval_t hash () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 void print (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 virtual void dump_dot_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 void dump_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 pretty_printer *pp,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 const char *prefix,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 bool is_last_child) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 virtual void dump_child_label (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 void remap_svalue_ids (const svalue_id_map &map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 virtual void remap_region_ids (const region_id_map &map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 virtual void walk_for_canonicalization (canonicalization *c) const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 void add_view (region_id view_rid, region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 region_id get_view (tree type, region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 bool is_view_p () const { return m_is_view; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 void validate (const region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 bool non_null_p (const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 protected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 region (region_id parent_rid, svalue_id sval_id, tree type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 region (const region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 virtual void add_to_hash (inchash::hash &hstate) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 virtual void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 void become_active_view (region_model &model, region_id this_rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 void deactivate_any_active_view (region_model &model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 void deactivate_view (region_model &model, region_id this_view_rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 region_id m_parent_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 svalue_id m_sval_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 tree m_type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 /* Child regions that are "views" (one per type). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 auto_vec<region_id> m_view_rids;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 bool m_is_view;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 region_id m_active_view_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 is_a_helper <region *>::test (region *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 /* Concrete region subclass for storing "primitive" types (integral types,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 pointers, etc). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 class primitive_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 primitive_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 : region (parent_rid, svalue_id::null (), type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 enum region_kind get_kind () const FINAL OVERRIDE { return RK_PRIMITIVE; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 /* A region that has children identified by tree keys.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 For example a stack frame has subregions per local, and a region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 for a struct has subregions per field. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 class map_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 typedef ordered_hash_map<tree, region_id> map_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 typedef map_t::iterator iterator_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 map_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 : region (parent_rid, svalue_id::null (), type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 map_region (const map_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 map_region *dyn_cast_map_region () FINAL OVERRIDE { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 void dump_dot_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 void dump_child_label (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 region_id get_or_create (region_model *model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 tree expr, tree type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 void unbind (tree expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 region_id *get (tree expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 void remap_region_ids (const region_id_map &map) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 tree get_tree_for_child_region (region_id child_rid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 tree get_tree_for_child_region (region *child,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 static bool can_merge_p (const map_region *map_region_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 const map_region *map_region_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 map_region *merged_map_region,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 region_id merged_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 virtual bool valid_key_p (tree key) const = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 svalue_id get_value_by_name (tree identifier,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 iterator_t begin () { return m_map.begin (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 iterator_t end () { return m_map.end (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 size_t elements () const { return m_map.elements (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 protected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 bool compare_fields (const map_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 void add_to_hash (inchash::hash &hstate) const OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 /* Mapping from tree to child region. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 map_t m_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 is_a_helper <map_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 return (reg->dyn_cast_map_region () != NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 /* Abstract subclass representing a region with fields
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 (either a struct or a union). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 class struct_or_union_region : public map_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 bool valid_key_p (tree key) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 protected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 struct_or_union_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 : map_region (parent_rid, type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 bool compare_fields (const struct_or_union_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 is_a_helper <struct_or_union_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 return (reg->get_kind () == RK_STRUCT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 || reg->get_kind () == RK_UNION);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 /* Concrete region subclass. A map_region representing a struct, using
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064 FIELD_DECLs for its keys. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 class struct_region : public struct_or_union_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 struct_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 : struct_or_union_region (parent_rid, type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 enum region_kind get_kind () const FINAL OVERRIDE { return RK_STRUCT; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079 bool compare_fields (const struct_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 is_a_helper <struct_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 return reg->get_kind () == RK_STRUCT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 /* Concrete region subclass. A map_region representing a union, using
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 FIELD_DECLs for its keys. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 class union_region : public struct_or_union_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 union_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 : struct_or_union_region (parent_rid, type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 gcc_assert (TREE_CODE (type) == UNION_TYPE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 enum region_kind get_kind () const FINAL OVERRIDE { return RK_UNION; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 bool compare_fields (const union_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 is_a_helper <union_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 return reg->get_kind () == RK_UNION;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125 /* Abstract map_region subclass for accessing decls, used as a base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 for function frames and for the globals region. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 class scope_region : public map_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132 protected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 scope_region (region_id parent_rid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 : map_region (parent_rid, NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 scope_region (const scope_region &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138 : map_region (other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 bool compare_fields (const scope_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 /* Concrete region subclass, representing a function frame on the stack,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 to contain the locals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 class frame_region : public scope_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 frame_region (region_id parent_rid, function *fun, int depth)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 : scope_region (parent_rid), m_fun (fun), m_depth (depth)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155 frame_region (const frame_region &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 : scope_region (other), m_fun (other.m_fun), m_depth (other.m_depth)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 /* region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 enum region_kind get_kind () const FINAL OVERRIDE { return RK_FRAME; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 /* map_region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 bool valid_key_p (tree key) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172 /* Accessors. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 function *get_function () const { return m_fun; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 int get_depth () const { return m_depth; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 bool compare_fields (const frame_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 function *m_fun;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 int m_depth;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188 is_a_helper <frame_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 return reg->get_kind () == RK_FRAME;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 /* Concrete region subclass, to hold global variables (data and bss). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 class globals_region : public scope_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 globals_region (region_id parent_rid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 : scope_region (parent_rid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 globals_region (const globals_region &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 : scope_region (other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209 /* region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 enum region_kind get_kind () const FINAL OVERRIDE { return RK_GLOBALS; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 /* map_region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 bool valid_key_p (tree key) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 bool compare_fields (const globals_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 is_a_helper <globals_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 return reg->get_kind () == RK_GLOBALS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 /* Concrete region subclass. A map_region representing the code, using
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 FUNCTION_DECLs for its keys. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 class code_region : public map_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 code_region (region_id parent_rid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 : map_region (parent_rid, NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240 code_region (const code_region &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 : map_region (other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 /* region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 enum region_kind get_kind () const FINAL OVERRIDE { return RK_CODE; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248 /* map_region vfunc. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 bool valid_key_p (tree key) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 region_id get_element (region_model *model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 svalue_id index_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 bool compare_fields (const code_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 is_a_helper <code_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 return reg->get_kind () == RK_CODE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 /* Concrete region subclass. A map_region representing the code for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 a particular function, using LABEL_DECLs for its keys. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274 class function_region : public map_region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 function_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 : map_region (parent_rid, type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 function_region (const function_region &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 : map_region (other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 /* region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 enum region_kind get_kind () const FINAL OVERRIDE { return RK_FUNCTION; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 /* map_region vfunc. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 bool valid_key_p (tree key) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 region_id get_element (region_model *model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295 svalue_id index_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 bool compare_fields (const function_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 is_a_helper <function_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 return reg->get_kind () == RK_FUNCTION;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 /* Concrete region subclass representing an array (or an array-like view
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 of a parent region of memory.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 This can't be a map_region as we can't use trees as the keys: there's
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 no guarantee about the uniqueness of an INTEGER_CST. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318 class array_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 #if 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322 wide_int m_test;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 typedef wide_int key_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 typedef int_hash <wide_int, -1, -2> hash_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 typedef ordered_hash_map<hash_t, region_id> map_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 #else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 typedef int key_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 typedef int_hash <int, -1, -2> int_hash_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 typedef ordered_hash_map<int_hash_t, region_id> map_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 typedef map_t::iterator iterator_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 array_region (region_id parent_rid, tree type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 : region (parent_rid, svalue_id::null (), type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 array_region (const array_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 void dump_dot_to_pp (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 void dump_child_label (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 /* region vfuncs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 enum region_kind get_kind () const FINAL OVERRIDE { return RK_ARRAY; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 region_id get_element (region_model *model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 svalue_id index_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 bool compare_fields (const array_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 static bool can_merge_p (const array_region *array_region_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 const array_region *array_region_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 array_region *merged_array_region,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 region_id merged_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 iterator_t begin () { return m_map.begin (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 iterator_t end () { return m_map.end (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 size_t elements () const { return m_map.elements (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 region_id get_or_create (region_model *model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 key_t key, tree type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378 // void unbind (int expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 region_id *get (key_t key);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 void remap_region_ids (const region_id_map &map) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 bool get_key_for_child_region (region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384 key_t *out) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 #if 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 bool get_key_for_child_region (region *child,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389 key_t *out) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 void add_to_hash (inchash::hash &hstate) const OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 static key_t key_from_constant (tree cst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 static int key_cmp (const void *, const void *);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 /* Mapping from tree to child region. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 map_t m_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412 is_a_helper <array_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 return reg->get_kind () == RK_ARRAY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 /* Concrete region subclass representing a stack, containing all stack
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420 frames, and implicitly providing a POISON_KIND_UNINIT value to all
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 child regions by default. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 class stack_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 stack_region (region_id parent_rid, svalue_id sval_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 : region (parent_rid, sval_id, NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 stack_region (const stack_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432 bool compare_fields (const stack_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 enum region_kind get_kind () const FINAL OVERRIDE { return RK_STACK; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 void dump_child_label (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 void push_frame (region_id frame_rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 region_id get_current_frame_id () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 svalue_id pop_frame (region_model *model, bool purge, purge_stats *stats,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 void remap_region_ids (const region_id_map &map) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 unsigned get_num_frames () const { return m_frame_rids.length (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 region_id get_frame_rid (unsigned i) const { return m_frame_rids[i]; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 static bool can_merge_p (const stack_region *stack_region_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 const stack_region *stack_region_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 svalue_id get_value_by_name (tree identifier,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470 auto_vec<region_id> m_frame_rids;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 is_a_helper <stack_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 return reg->get_kind () == RK_STACK;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 /* Concrete region subclass: a region within which regions can be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 dynamically allocated. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 class heap_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 heap_region (region_id parent_rid, svalue_id sval_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 : region (parent_rid, sval_id, NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494 heap_region (const heap_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 bool compare_fields (const heap_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500 enum region_kind get_kind () const FINAL OVERRIDE { return RK_HEAP; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 static bool can_merge_p (const heap_region *heap_a, region_id heap_a_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 const heap_region *heap_b, region_id heap_b_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 heap_region *merged_heap, region_id merged_heap_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 is_a_helper <heap_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518 return reg->get_kind () == RK_HEAP;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 /* Concrete region subclass. The root region, containing all regions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 (either directly, or as descendents).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 Unique within a region_model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 class root_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 root_region ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 root_region (const root_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 bool compare_fields (const root_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 enum region_kind get_kind () const FINAL OVERRIDE { return RK_ROOT; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 void dump_child_label (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541 region_id child_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 region_id push_frame (region_model *model, function *fun,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 vec<svalue_id> *arg_sids,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 region_id get_current_frame_id (const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 svalue_id pop_frame (region_model *model, bool purge, purge_stats *stats,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 region_id ensure_stack_region (region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 region_id get_stack_region_id () const { return m_stack_rid; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 stack_region *get_stack_region (const region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 region_id ensure_globals_region (region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 region_id get_globals_region_id () const { return m_globals_rid; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 globals_region *get_globals_region (const region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 region_id ensure_code_region (region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561 code_region *get_code_region (const region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 region_id ensure_heap_region (region_model *model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564 heap_region *get_heap_region (const region_model *model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 void remap_region_ids (const region_id_map &map) FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 static bool can_merge_p (const root_region *root_region_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 const root_region *root_region_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 root_region *merged_root_region,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 model_merger *merger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 svalue_id get_value_by_name (tree identifier,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 const region_model &model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 void print_fields (const region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 region_id this_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 region_id m_stack_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 region_id m_globals_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587 region_id m_code_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 region_id m_heap_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594 template <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 inline bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 is_a_helper <root_region *>::test (region *reg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 return reg->get_kind () == RK_ROOT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603 /* Concrete region subclass: a region to use when dereferencing an unknown
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 class symbolic_region : public region
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 symbolic_region (region_id parent_rid, tree type, bool possibly_null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 : region (parent_rid, svalue_id::null (), type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611 m_possibly_null (possibly_null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613 symbolic_region (const symbolic_region &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 const symbolic_region *dyn_cast_symbolic_region () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 { return this; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 bool compare_fields (const symbolic_region &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620 region *clone () const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 enum region_kind get_kind () const FINAL OVERRIDE { return RK_SYMBOLIC; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 void walk_for_canonicalization (canonicalization *c) const FINAL OVERRIDE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 bool m_possibly_null;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 /* A region_model encapsulates a representation of the state of memory, with
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 a tree of regions, along with their associated values.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 The representation is graph-like because values can be pointers to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 regions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 It also stores a constraint_manager, capturing relationships between
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634 the values. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 class region_model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 region_model ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640 region_model (const region_model &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 ~region_model ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 #if 0//__cplusplus >= 201103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 region_model (region_model &&other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 region_model &operator= (const region_model &other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649 bool operator== (const region_model &other) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650 bool operator!= (const region_model &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 return !(*this == other);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655 hashval_t hash () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 void print (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 void print_svalue (svalue_id sid, pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661 void dump_dot_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662 void dump_dot_to_file (FILE *fp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 void dump_dot (const char *path) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 void dump_to_pp (pretty_printer *pp, bool summarize) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 void dump (FILE *fp, bool summarize) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 void dump (bool summarize) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 void debug () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671 void validate () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 void canonicalize (region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 bool canonicalized_p () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 void check_for_poison (tree expr, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 void on_assignment (const gassign *stmt, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 bool on_call_pre (const gcall *stmt, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 void on_call_post (const gcall *stmt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 bool unknown_side_effects,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 void handle_unrecognized_call (const gcall *call,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 void on_return (const greturn *stmt, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 void on_setjmp (const gcall *stmt, const exploded_node *enode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 void on_longjmp (const gcall *longjmp_call, const gcall *setjmp_call,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 int setjmp_stack_depth, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 void update_for_phis (const supernode *snode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691 const cfg_superedge *last_cfg_superedge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 void handle_phi (const gphi *phi,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 tree lhs, tree rhs, bool is_back_edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 bool maybe_update_for_edge (const superedge &edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 const gimple *last_stmt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 region_id get_root_rid () const { return m_root_rid; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 root_region *get_root_region () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 region_id get_stack_region_id () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706 region_id push_frame (function *fun, vec<svalue_id> *arg_sids,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 region_id get_current_frame_id () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 function * get_current_function () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 svalue_id pop_frame (bool purge, purge_stats *stats,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 int get_stack_depth () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713 function *get_function_at_depth (unsigned depth) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 region_id get_globals_region_id () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 svalue_id add_svalue (svalue *sval);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 void replace_svalue (svalue_id sid, svalue *new_sval);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 region_id add_region (region *r);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 region_id add_region_for_type (region_id parent_rid, tree type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 svalue *get_svalue (svalue_id sval_id) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 region *get_region (region_id rid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 template <typename Subclass>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728 Subclass *get_region (region_id rid) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 region *result = get_region (rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 if (result)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 gcc_assert (is_a<Subclass *> (result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 return (Subclass *)result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 region_id get_lvalue (path_var pv, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737 region_id get_lvalue (tree expr, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738 svalue_id get_rvalue (path_var pv, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739 svalue_id get_rvalue (tree expr, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 svalue_id get_or_create_ptr_svalue (tree ptr_type, region_id id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742 svalue_id get_or_create_constant_svalue (tree cst_expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 svalue_id get_svalue_for_fndecl (tree ptr_type, tree fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 svalue_id get_svalue_for_label (tree ptr_type, tree label);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 region_id get_region_for_fndecl (tree fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 region_id get_region_for_label (tree label);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749 svalue_id maybe_cast (tree type, svalue_id sid, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750 svalue_id maybe_cast_1 (tree type, svalue_id sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 region_id get_field_region (region_id rid, tree field);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 region_id deref_rvalue (svalue_id ptr_sid, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755 region_id deref_rvalue (tree ptr, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 void set_value (region_id lhs_rid, svalue_id rhs_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759 svalue_id set_to_new_unknown_value (region_id dst_rid, tree type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 tristate eval_condition (svalue_id lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764 svalue_id rhs) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765 tristate eval_condition_without_cm (svalue_id lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767 svalue_id rhs) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768 tristate eval_condition (tree lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770 tree rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775 tree maybe_get_constant (svalue_id sid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 region_id add_new_malloc_region ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779 tree get_representative_tree (svalue_id sid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780 path_var get_representative_path_var (region_id rid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 void get_path_vars_for_svalue (svalue_id sid, vec<path_var> *out) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 void purge_unused_svalues (purge_stats *out,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784 region_model_context *ctxt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 svalue_id *known_used_sid = NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786 void remap_svalue_ids (const svalue_id_map &map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787 void remap_region_ids (const region_id_map &map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789 void purge_regions (const region_id_set &set,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 purge_stats *stats,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 logger *logger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 unsigned get_num_svalues () const { return m_svalues.length (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794 unsigned get_num_regions () const { return m_regions.length (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 /* For selftests. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 constraint_manager *get_constraints ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799 return m_constraints;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 void get_descendents (region_id rid, region_id_set *out,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803 region_id exclude_rid) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805 void delete_region_and_descendents (region_id rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806 enum poison_kind pkind,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 purge_stats *stats,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808 logger *logger);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 bool can_merge_with_p (const region_model &other_model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811 region_model *out_model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 svalue_id_merger_mapping *out) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813 bool can_merge_with_p (const region_model &other_model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814 region_model *out_model) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 svalue_id get_value_by_name (const char *name) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818 svalue_id convert_byte_offset_to_array_index (tree ptr_type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 svalue_id offset_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821 region_id get_or_create_mem_ref (tree type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 svalue_id ptr_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823 svalue_id offset_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825 region_id get_or_create_pointer_plus_expr (tree type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826 svalue_id ptr_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 svalue_id offset_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829 region_id get_or_create_view (region_id raw_rid, tree type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831 tree get_fndecl_for_call (const gcall *call,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 region_id get_lvalue_1 (path_var pv, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836 svalue_id get_rvalue_1 (path_var pv, region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 void add_any_constraints_from_ssa_def_stmt (tree lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840 tree rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843 void update_for_call_superedge (const call_superedge &call_edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 void update_for_return_superedge (const return_superedge &return_edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847 void update_for_call_summary (const callgraph_superedge &cg_sedge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 bool apply_constraints_for_gcond (const cfg_superedge &edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 const gcond *cond_stmt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852 bool apply_constraints_for_gswitch (const switch_cfg_superedge &edge,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 const gswitch *switch_stmt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854 region_model_context *ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 void poison_any_pointers_to_bad_regions (const region_id_set &bad_regions,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857 enum poison_kind pkind);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859 void dump_summary_of_map (pretty_printer *pp, map_region *map_region,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860 bool *is_first) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 auto_delete_vec<svalue> m_svalues;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863 auto_delete_vec<region> m_regions;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 region_id m_root_rid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 constraint_manager *m_constraints; // TODO: embed, rather than dynalloc?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868 /* Some region_model activity could lead to warnings (e.g. attempts to use an
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869 uninitialized value). This abstract base class encapsulates an interface
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870 for the region model to use when emitting such warnings.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 It also provides an interface for being notified about svalue_ids being
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 remapped, and being deleted.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 Having this as an abstract base class allows us to support the various
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876 operations needed by program_state in the analyzer within region_model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877 whilst keeping them somewhat modularized. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879 class region_model_context
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 virtual void warn (pending_diagnostic *d) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 /* Hook for clients that store svalue_id instances, so that they
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 can remap their IDs when the underlying region_model renumbers
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886 the IDs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887 virtual void remap_svalue_ids (const svalue_id_map &map) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 #if 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890 /* Return true if if's OK to purge SID when simplifying state.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891 Subclasses can return false for values that have sm state,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 to avoid generating "leak" false positives. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 virtual bool can_purge_p (svalue_id sid) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 /* Hook for clients to be notified when a range of SIDs have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897 been purged, so that they can purge state relating to those
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 values (and potentially emit warnings about leaks).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899 All SIDs from FIRST_PURGED_SID numerically upwards are being
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900 purged.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901 The return values is a count of how many items of data the client
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902 has purged (potentially for use in selftests).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903 MAP has already been applied to the IDs, but is provided in case
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 the client needs to figure out the old IDs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 virtual int on_svalue_purge (svalue_id first_purged_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906 const svalue_id_map &map) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908 virtual logger *get_logger () = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910 /* Hook for clients to be notified when CHILD_SID is created
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 from PARENT_SID, when "inheriting" a value for a region from a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 parent region.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913 This exists so that state machines that inherit state can
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 propagate the state from parent to child. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915 virtual void on_inherited_svalue (svalue_id parent_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916 svalue_id child_sid) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918 /* Hook for clients to be notified when DST_SID is created
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919 (or reused) as a cast from SRC_SID.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 This exists so that state machines can propagate the state
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 from SRC_SID to DST_SID. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922 virtual void on_cast (svalue_id src_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 svalue_id dst_sid) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925 /* Hook for clients to be notified when the condition
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 "LHS OP RHS" is added to the region model.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927 This exists so that state machines can detect tests on edges,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928 and use them to trigger sm-state transitions (e.g. transitions due
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929 to ptrs becoming known to be NULL or non-NULL, rather than just
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 "unchecked") */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 virtual void on_condition (tree lhs, enum tree_code op, tree rhs) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933 /* Hooks for clients to be notified when an unknown change happens
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934 to SID (in response to a call to an unknown function). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935 virtual void on_unknown_change (svalue_id sid) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937 /* Hooks for clients to be notified when a phi node is handled,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 where RHS is the pertinent argument. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939 virtual void on_phi (const gphi *phi, tree rhs) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 /* A bundle of data for use when attempting to merge two region_model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943 instances to make a third. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1944
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1945 struct model_merger
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1946 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1947 model_merger (const region_model *model_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1948 const region_model *model_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1949 region_model *merged_model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1950 svalue_id_merger_mapping *sid_mapping)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1951 : m_model_a (model_a), m_model_b (model_b),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1952 m_merged_model (merged_model),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1953 m_map_regions_from_a_to_m (model_a->get_num_regions ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1954 m_map_regions_from_b_to_m (model_b->get_num_regions ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1955 m_sid_mapping (sid_mapping)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1956 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1957 gcc_assert (sid_mapping);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1958 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1959
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1960 void dump_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1961 void dump (FILE *fp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1962 void dump () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1963
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1964 template <typename Subclass>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1965 Subclass *get_region_a (region_id rid_a) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1966 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1967 return m_model_a->get_region <Subclass> (rid_a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1968 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1969
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1970 template <typename Subclass>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1971 Subclass *get_region_b (region_id rid_b) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1972 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1973 return m_model_b->get_region <Subclass> (rid_b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1974 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1975
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1976 bool can_merge_values_p (svalue_id sid_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1977 svalue_id sid_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1978 svalue_id *merged_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1979
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1980 void record_regions (region_id a_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1981 region_id b_rid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1982 region_id merged_rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1983
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1984 void record_svalues (svalue_id a_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1985 svalue_id b_sid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1986 svalue_id merged_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1987
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1988 const region_model *m_model_a;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1989 const region_model *m_model_b;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1990 region_model *m_merged_model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1991
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1992 one_way_region_id_map m_map_regions_from_a_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1993 one_way_region_id_map m_map_regions_from_b_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1994 svalue_id_merger_mapping *m_sid_mapping;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1995 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1996
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1997 /* A bundle of data that can be optionally generated during merger of two
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1998 region_models that describes how svalue_ids in each of the two inputs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1999 are mapped to svalue_ids in the merged output.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2000
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2001 For use when merging sm-states within program_state. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2002
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2003 struct svalue_id_merger_mapping
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2004 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2005 svalue_id_merger_mapping (const region_model &a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2006 const region_model &b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2007
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2008 void dump_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2009 void dump (FILE *fp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2010 void dump () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2011
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2012 one_way_svalue_id_map m_map_from_a_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2013 one_way_svalue_id_map m_map_from_b_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2014 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2015
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2016 /* A bundle of data used when canonicalizing a region_model so that the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2017 order of regions and svalues is in a predictable order (thus increasing
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2018 the chance of two region_models being equal).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2019
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2020 This object is used to keep track of a recursive traversal across the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2021 svalues and regions within the model, made in a deterministic order,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2022 assigning new ids the first time each region or svalue is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2023 encountered. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2024
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2025 struct canonicalization
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2026 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2027 canonicalization (const region_model &model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2028 void walk_rid (region_id rid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2029 void walk_sid (svalue_id sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2030
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2031 void dump_to_pp (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2032 void dump (FILE *fp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2033 void dump () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2034
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2035 const region_model &m_model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2036 /* Maps from existing IDs to new IDs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2037 region_id_map m_rid_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2038 svalue_id_map m_sid_map;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2039 /* The next IDs to hand out. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2040 int m_next_rid_int;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2041 int m_next_sid_int;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2042 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2043
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2044 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2045
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2046 namespace inchash
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2047 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2048 extern void add (svalue_id sid, hash &hstate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2049 extern void add (region_id rid, hash &hstate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2050 } // namespace inchash
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2051
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2052 extern void debug (const region_model &rmodel);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2053
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2054 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2055
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2056 #if CHECKING_P
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2057
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2058 namespace selftest {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2059
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2060 using namespace ::selftest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2061
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2062 /* An implementation of region_model_context for use in selftests, which
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2063 stores any pending_diagnostic instances passed to it. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2064
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2065 class test_region_model_context : public region_model_context
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2066 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2067 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2068 void warn (pending_diagnostic *d) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2069 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2070 m_diagnostics.safe_push (d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2071 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2072
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2073 void remap_svalue_ids (const svalue_id_map &) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2074 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2075 /* Empty. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2076 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2077
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2078 #if 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2079 bool can_purge_p (svalue_id) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2080 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2081 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2082 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2083 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2084
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2085 int on_svalue_purge (svalue_id, const svalue_id_map &) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2086 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2087 /* Empty. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2088 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2089 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2090
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2091 logger *get_logger () FINAL OVERRIDE { return NULL; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2092
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2093 void on_inherited_svalue (svalue_id parent_sid ATTRIBUTE_UNUSED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2094 svalue_id child_sid ATTRIBUTE_UNUSED)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2095 FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2096 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2097 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2098
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2099 void on_cast (svalue_id src_sid ATTRIBUTE_UNUSED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2100 svalue_id dst_sid ATTRIBUTE_UNUSED) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2101 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2102 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2104 unsigned get_num_diagnostics () const { return m_diagnostics.length (); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2106 void on_condition (tree lhs ATTRIBUTE_UNUSED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2107 enum tree_code op ATTRIBUTE_UNUSED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2108 tree rhs ATTRIBUTE_UNUSED) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2109 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2112 void on_unknown_change (svalue_id sid ATTRIBUTE_UNUSED) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2114 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2116 void on_phi (const gphi *phi ATTRIBUTE_UNUSED,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2117 tree rhs ATTRIBUTE_UNUSED) FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2118 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2119 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2121 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2122 /* Implicitly delete any diagnostics in the dtor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2123 auto_delete_vec<pending_diagnostic> m_diagnostics;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2124 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2126 /* Attempt to add the constraint (LHS OP RHS) to MODEL.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2127 Verify that MODEL remains satisfiable. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2128
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2129 #define ADD_SAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2130 SELFTEST_BEGIN_STMT \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2131 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2132 ASSERT_TRUE (sat); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2133 SELFTEST_END_STMT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2135 /* Attempt to add the constraint (LHS OP RHS) to MODEL.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2136 Verify that the result is not satisfiable. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2137
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2138 #define ADD_UNSAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2139 SELFTEST_BEGIN_STMT \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2140 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2141 ASSERT_FALSE (sat); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2142 SELFTEST_END_STMT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2143
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2144 /* Implementation detail of the ASSERT_CONDITION_* macros. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2146 void assert_condition (const location &loc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2147 region_model &model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2148 tree lhs, tree_code op, tree rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2149 tristate expected);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2151 /* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2152 as "true". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2153
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2154 #define ASSERT_CONDITION_TRUE(REGION_MODEL, LHS, OP, RHS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2155 SELFTEST_BEGIN_STMT \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2156 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2157 tristate (tristate::TS_TRUE)); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2158 SELFTEST_END_STMT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2159
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2160 /* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2161 as "false". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2163 #define ASSERT_CONDITION_FALSE(REGION_MODEL, LHS, OP, RHS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2164 SELFTEST_BEGIN_STMT \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2165 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2166 tristate (tristate::TS_FALSE)); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2167 SELFTEST_END_STMT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2169 /* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2170 as "unknown". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2172 #define ASSERT_CONDITION_UNKNOWN(REGION_MODEL, LHS, OP, RHS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2173 SELFTEST_BEGIN_STMT \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2174 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2175 tristate (tristate::TS_UNKNOWN)); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2176 SELFTEST_END_STMT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2177
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2178 } /* end of namespace selftest. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2179
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2180 #endif /* #if CHECKING_P */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2182 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2183
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2184 #endif /* GCC_ANALYZER_REGION_MODEL_H */