Branch data Line data Source code
1 : : /* Consolidation of svalues and regions.
2 : : Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_ANALYZER_REGION_MODEL_MANAGER_H
22 : : #define GCC_ANALYZER_REGION_MODEL_MANAGER_H
23 : :
24 : : namespace ana {
25 : :
26 : : /* A class responsible for owning and consolidating region and svalue
27 : : instances.
28 : : region and svalue instances are immutable as far as clients are
29 : : concerned, so they are provided as "const" ptrs. */
30 : :
31 : : class region_model_manager
32 : : {
33 : : public:
34 : : region_model_manager (logger *logger = NULL);
35 : : ~region_model_manager ();
36 : :
37 : : unsigned get_num_symbols () const { return m_next_symbol_id; }
38 : 360738 : unsigned alloc_symbol_id () { return m_next_symbol_id++; }
39 : :
40 : : /* call_string consolidation. */
41 : 12870 : const call_string &get_empty_call_string () const
42 : : {
43 : 12870 : return m_empty_call_string;
44 : : }
45 : :
46 : : /* svalue consolidation. */
47 : : const svalue *get_or_create_constant_svalue (tree type, tree cst_expr);
48 : : const svalue *get_or_create_constant_svalue (tree cst_expr);
49 : : const svalue *get_or_create_int_cst (tree type, const poly_wide_int_ref &cst);
50 : : const svalue *get_or_create_null_ptr (tree pointer_type);
51 : : const svalue *get_or_create_unknown_svalue (tree type);
52 : : const svalue *get_or_create_setjmp_svalue (const setjmp_record &r,
53 : : tree type);
54 : : const svalue *get_or_create_poisoned_svalue (enum poison_kind kind,
55 : : tree type);
56 : : const svalue *get_or_create_initial_value (const region *reg,
57 : : bool check_poisoned = true);
58 : : const svalue *get_ptr_svalue (tree ptr_type, const region *pointee);
59 : : const svalue *get_or_create_unaryop (tree type, enum tree_code op,
60 : : const svalue *arg);
61 : : const svalue *get_or_create_cast (tree type, const svalue *arg);
62 : : const svalue *get_or_create_binop (tree type,
63 : : enum tree_code op,
64 : : const svalue *arg0, const svalue *arg1);
65 : : const svalue *get_or_create_sub_svalue (tree type,
66 : : const svalue *parent_svalue,
67 : : const region *subregion);
68 : : const svalue *get_or_create_repeated_svalue (tree type,
69 : : const svalue *outer_size,
70 : : const svalue *inner_svalue);
71 : : const svalue *get_or_create_bits_within (tree type,
72 : : const bit_range &bits,
73 : : const svalue *inner_svalue);
74 : : const svalue *get_or_create_unmergeable (const svalue *arg);
75 : : const svalue *get_or_create_widening_svalue (tree type,
76 : : const function_point &point,
77 : : const svalue *base_svalue,
78 : : const svalue *iter_svalue);
79 : : const svalue *get_or_create_compound_svalue (tree type,
80 : : const binding_map &map);
81 : : const svalue *get_or_create_conjured_svalue (tree type, const gimple *stmt,
82 : : const region *id_reg,
83 : : const conjured_purge &p,
84 : : unsigned idx = 0);
85 : : const svalue *
86 : : get_or_create_asm_output_svalue (tree type,
87 : : const gasm *asm_stmt,
88 : : unsigned output_idx,
89 : : const vec<const svalue *> &inputs);
90 : : const svalue *
91 : : get_or_create_asm_output_svalue (tree type,
92 : : const char *asm_string,
93 : : unsigned output_idx,
94 : : unsigned num_outputs,
95 : : const vec<const svalue *> &inputs);
96 : : const svalue *
97 : : get_or_create_const_fn_result_svalue (tree type,
98 : : tree fndecl,
99 : : const vec<const svalue *> &inputs);
100 : :
101 : : const svalue *maybe_get_char_from_string_cst (tree string_cst,
102 : : tree byte_offset_cst);
103 : :
104 : : /* Dynamically-allocated svalue instances.
105 : : The number of these within the analysis can grow arbitrarily.
106 : : They are still owned by the manager. */
107 : : const svalue *create_unique_svalue (tree type);
108 : :
109 : : /* region consolidation. */
110 : 6394 : const root_region *get_root_region () const { return &m_root_region; }
111 : 4 : const stack_region * get_stack_region () const { return &m_stack_region; }
112 : 4 : const heap_region *get_heap_region () const { return &m_heap_region; }
113 : 4 : const code_region *get_code_region () const { return &m_code_region; }
114 : 4 : const globals_region *get_globals_region () const
115 : : {
116 : 4 : return &m_globals_region;
117 : : }
118 : 934 : const errno_region *get_errno_region () const { return &m_errno_region; }
119 : : const function_region *get_region_for_fndecl (tree fndecl);
120 : : const label_region *get_region_for_label (tree label);
121 : : const decl_region *get_region_for_global (tree expr);
122 : : const region *get_field_region (const region *parent, tree field);
123 : : const region *get_element_region (const region *parent,
124 : : tree element_type,
125 : : const svalue *index);
126 : : const region *get_offset_region (const region *parent,
127 : : tree type,
128 : : const svalue *byte_offset);
129 : : const region *get_sized_region (const region *parent,
130 : : tree type,
131 : : const svalue *byte_size_sval);
132 : : const region *get_cast_region (const region *original_region,
133 : : tree type);
134 : : const frame_region *get_frame_region (const frame_region *calling_frame,
135 : : const function &fun);
136 : : const region *get_symbolic_region (const svalue *sval);
137 : : const string_region *get_region_for_string (tree string_cst);
138 : : const region *get_bit_range (const region *parent, tree type,
139 : : const bit_range &bits);
140 : : const var_arg_region *get_var_arg_region (const frame_region *parent,
141 : : unsigned idx);
142 : :
143 : : const region *get_unknown_symbolic_region (tree region_type);
144 : :
145 : : const region *
146 : : get_region_for_unexpected_tree_code (region_model_context *ctxt,
147 : : tree t,
148 : : const dump_location_t &loc);
149 : :
150 : 5454310 : store_manager *get_store_manager () { return &m_store_mgr; }
151 : 22144 : bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }
152 : :
153 : 362311 : known_function_manager *get_known_function_manager ()
154 : : {
155 : 359114 : return &m_known_fn_mgr;
156 : : }
157 : :
158 : : /* Dynamically-allocated region instances.
159 : : The number of these within the analysis can grow arbitrarily.
160 : : They are still owned by the manager. */
161 : : const region *
162 : : get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use);
163 : : const region *create_region_for_alloca (const frame_region *frame);
164 : :
165 : : void log_stats (logger *logger, bool show_objs) const;
166 : :
167 : 6624 : void begin_checking_feasibility (void) { m_checking_feasibility = true; }
168 : 6624 : void end_checking_feasibility (void) { m_checking_feasibility = false; }
169 : :
170 : 329201 : logger *get_logger () const { return m_logger; }
171 : :
172 : : void dump_untracked_regions () const;
173 : :
174 : : const svalue *maybe_fold_binop (tree type, enum tree_code op,
175 : : const svalue *arg0, const svalue *arg1);
176 : : private:
177 : : bool too_complex_p (const complexity &c) const;
178 : : bool reject_if_too_complex (svalue *sval);
179 : :
180 : : const svalue *maybe_fold_unaryop (tree type, enum tree_code op,
181 : : const svalue *arg);
182 : : const svalue *maybe_fold_sub_svalue (tree type,
183 : : const svalue *parent_svalue,
184 : : const region *subregion);
185 : : const svalue *maybe_fold_repeated_svalue (tree type,
186 : : const svalue *outer_size,
187 : : const svalue *inner_svalue);
188 : : const svalue *maybe_fold_bits_within_svalue (tree type,
189 : : const bit_range &bits,
190 : : const svalue *inner_svalue);
191 : : const svalue *maybe_undo_optimize_bit_field_compare (tree type,
192 : : const compound_svalue *compound_sval,
193 : : tree cst, const svalue *arg1);
194 : : const svalue *maybe_fold_asm_output_svalue (tree type,
195 : : const vec<const svalue *> &inputs);
196 : :
197 : : logger *m_logger;
198 : :
199 : : unsigned m_next_symbol_id;
200 : :
201 : : const call_string m_empty_call_string;
202 : :
203 : : root_region m_root_region;
204 : : stack_region m_stack_region;
205 : : heap_region m_heap_region;
206 : :
207 : : /* svalue consolidation. */
208 : : typedef hash_map<constant_svalue::key_t, constant_svalue *> constants_map_t;
209 : : constants_map_t m_constants_map;
210 : :
211 : : typedef hash_map<tree, unknown_svalue *> unknowns_map_t;
212 : : unknowns_map_t m_unknowns_map;
213 : : const unknown_svalue *m_unknown_NULL;
214 : :
215 : : typedef hash_map<poisoned_svalue::key_t,
216 : : poisoned_svalue *> poisoned_values_map_t;
217 : : poisoned_values_map_t m_poisoned_values_map;
218 : :
219 : : typedef hash_map<setjmp_svalue::key_t,
220 : : setjmp_svalue *> setjmp_values_map_t;
221 : : setjmp_values_map_t m_setjmp_values_map;
222 : :
223 : : typedef hash_map<const region *, initial_svalue *> initial_values_map_t;
224 : : initial_values_map_t m_initial_values_map;
225 : :
226 : : typedef hash_map<region_svalue::key_t, region_svalue *> pointer_values_map_t;
227 : : pointer_values_map_t m_pointer_values_map;
228 : :
229 : : typedef hash_map<unaryop_svalue::key_t,
230 : : unaryop_svalue *> unaryop_values_map_t;
231 : : unaryop_values_map_t m_unaryop_values_map;
232 : :
233 : : typedef hash_map<binop_svalue::key_t, binop_svalue *> binop_values_map_t;
234 : : binop_values_map_t m_binop_values_map;
235 : :
236 : : typedef hash_map<sub_svalue::key_t, sub_svalue *> sub_values_map_t;
237 : : sub_values_map_t m_sub_values_map;
238 : :
239 : : typedef hash_map<repeated_svalue::key_t,
240 : : repeated_svalue *> repeated_values_map_t;
241 : : repeated_values_map_t m_repeated_values_map;
242 : :
243 : : typedef hash_map<bits_within_svalue::key_t,
244 : : bits_within_svalue *> bits_within_values_map_t;
245 : : bits_within_values_map_t m_bits_within_values_map;
246 : :
247 : : typedef hash_map<const svalue *,
248 : : unmergeable_svalue *> unmergeable_values_map_t;
249 : : unmergeable_values_map_t m_unmergeable_values_map;
250 : :
251 : : typedef hash_map<widening_svalue::key_t,
252 : : widening_svalue */*,
253 : : widening_svalue::key_t::hash_map_traits*/>
254 : : widening_values_map_t;
255 : : widening_values_map_t m_widening_values_map;
256 : :
257 : : typedef hash_map<compound_svalue::key_t,
258 : : compound_svalue *> compound_values_map_t;
259 : : compound_values_map_t m_compound_values_map;
260 : :
261 : : typedef hash_map<conjured_svalue::key_t,
262 : : conjured_svalue *> conjured_values_map_t;
263 : : conjured_values_map_t m_conjured_values_map;
264 : :
265 : : typedef hash_map<asm_output_svalue::key_t,
266 : : asm_output_svalue *> asm_output_values_map_t;
267 : : asm_output_values_map_t m_asm_output_values_map;
268 : :
269 : : typedef hash_map<const_fn_result_svalue::key_t,
270 : : const_fn_result_svalue *> const_fn_result_values_map_t;
271 : : const_fn_result_values_map_t m_const_fn_result_values_map;
272 : :
273 : : bool m_checking_feasibility;
274 : :
275 : : /* "Dynamically-allocated" svalue instances.
276 : : The number of these within the analysis can grow arbitrarily.
277 : : They are still owned by the manager. */
278 : : auto_delete_vec<svalue> m_managed_dynamic_svalues;
279 : :
280 : : /* Maximum complexity of svalues that weren't rejected. */
281 : : complexity m_max_complexity;
282 : :
283 : : /* region consolidation. */
284 : :
285 : : code_region m_code_region;
286 : : typedef hash_map<tree, function_region *> fndecls_map_t;
287 : : typedef fndecls_map_t::iterator fndecls_iterator_t;
288 : : fndecls_map_t m_fndecls_map;
289 : :
290 : : typedef hash_map<tree, label_region *> labels_map_t;
291 : : typedef labels_map_t::iterator labels_iterator_t;
292 : : labels_map_t m_labels_map;
293 : :
294 : : globals_region m_globals_region;
295 : : typedef hash_map<tree, decl_region *> globals_map_t;
296 : : typedef globals_map_t::iterator globals_iterator_t;
297 : : globals_map_t m_globals_map;
298 : :
299 : : thread_local_region m_thread_local_region;
300 : : errno_region m_errno_region;
301 : :
302 : : consolidation_map<field_region> m_field_regions;
303 : : consolidation_map<element_region> m_element_regions;
304 : : consolidation_map<offset_region> m_offset_regions;
305 : : consolidation_map<sized_region> m_sized_regions;
306 : : consolidation_map<cast_region> m_cast_regions;
307 : : consolidation_map<frame_region> m_frame_regions;
308 : : consolidation_map<symbolic_region> m_symbolic_regions;
309 : :
310 : : typedef hash_map<tree, string_region *> string_map_t;
311 : : string_map_t m_string_map;
312 : :
313 : : consolidation_map<bit_range_region> m_bit_range_regions;
314 : : consolidation_map<var_arg_region> m_var_arg_regions;
315 : :
316 : : store_manager m_store_mgr;
317 : :
318 : : bounded_ranges_manager *m_range_mgr;
319 : :
320 : : known_function_manager m_known_fn_mgr;
321 : :
322 : : /* "Dynamically-allocated" region instances.
323 : : The number of these within the analysis can grow arbitrarily.
324 : : They are still owned by the manager. */
325 : : auto_delete_vec<region> m_managed_dynamic_regions;
326 : : };
327 : :
328 : : } // namespace ana
329 : :
330 : : #endif /* GCC_ANALYZER_REGION_MODEL_MANAGER_H */
|