Line data Source code
1 : /* Consolidation of svalues and regions.
2 : Copyright (C) 2020-2026 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 = nullptr);
35 : ~region_model_manager ();
36 :
37 : unsigned get_num_symbols () const { return m_next_symbol_id; }
38 394613 : unsigned alloc_symbol_id () { return m_next_symbol_id++; }
39 :
40 : /* call_string consolidation. */
41 13760 : const call_string &get_empty_call_string () const
42 : {
43 10285 : 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 supernode *snode,
77 : const svalue *base_svalue,
78 : const svalue *iter_svalue);
79 : const svalue *get_or_create_compound_svalue (tree type,
80 : concrete_binding_map &&map);
81 : const svalue *get_or_create_compound_svalue (tree type,
82 : const concrete_binding_map &map);
83 : const svalue *get_or_create_conjured_svalue (tree type, const gimple *stmt,
84 : const region *id_reg,
85 : const conjured_purge &p,
86 : unsigned idx = 0);
87 : const svalue *
88 : get_or_create_asm_output_svalue (tree type,
89 : const gasm *asm_stmt,
90 : unsigned output_idx,
91 : const vec<const svalue *> &inputs);
92 : const svalue *
93 : get_or_create_asm_output_svalue (tree type,
94 : const char *asm_string,
95 : unsigned output_idx,
96 : unsigned num_outputs,
97 : const vec<const svalue *> &inputs);
98 : const svalue *
99 : get_or_create_const_fn_result_svalue (tree type,
100 : tree fndecl,
101 : const vec<const svalue *> &inputs);
102 :
103 : const svalue *maybe_get_char_from_cst (tree data_cst,
104 : tree byte_offset_cst);
105 : const svalue *maybe_get_char_from_string_cst (tree string_cst,
106 : tree byte_offset_cst);
107 : const svalue *maybe_get_char_from_raw_data_cst (tree raw_data_cst,
108 : tree byte_offset_cst);
109 :
110 : /* Dynamically-allocated svalue instances.
111 : The number of these within the analysis can grow arbitrarily.
112 : They are still owned by the manager. */
113 : const svalue *create_unique_svalue (tree type);
114 :
115 : /* region consolidation. */
116 6846 : const root_region *get_root_region () const { return &m_root_region; }
117 4 : const stack_region * get_stack_region () const { return &m_stack_region; }
118 4 : const heap_region *get_heap_region () const { return &m_heap_region; }
119 4 : const code_region *get_code_region () const { return &m_code_region; }
120 4 : const globals_region *get_globals_region () const
121 : {
122 4 : return &m_globals_region;
123 : }
124 1056 : const errno_region *get_errno_region () const { return &m_errno_region; }
125 : const function_region *get_region_for_fndecl (tree fndecl);
126 : const label_region *get_region_for_label (tree label);
127 : const decl_region *get_region_for_global (tree expr);
128 : const region *get_field_region (const region *parent, tree field);
129 : const region *get_element_region (const region *parent,
130 : tree element_type,
131 : const svalue *index);
132 : const region *get_offset_region (const region *parent,
133 : tree type,
134 : const svalue *byte_offset);
135 : const region *get_sized_region (const region *parent,
136 : tree type,
137 : const svalue *byte_size_sval);
138 : const region *get_cast_region (const region *original_region,
139 : tree type);
140 : const frame_region *get_frame_region (const frame_region *calling_frame,
141 : const function &fun);
142 : const region *get_symbolic_region (const svalue *sval);
143 : const string_region *get_region_for_string (tree string_cst);
144 : const region *get_bit_range (const region *parent, tree type,
145 : const bit_range &bits);
146 : const var_arg_region *get_var_arg_region (const frame_region *parent,
147 : unsigned idx);
148 :
149 : const region *get_unknown_symbolic_region (tree region_type);
150 :
151 : const region *
152 : get_region_for_unexpected_tree_code (region_model_context *ctxt,
153 : tree t,
154 : const dump_location_t &loc);
155 :
156 5807755 : store_manager *get_store_manager () { return &m_store_mgr; }
157 21321 : bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }
158 :
159 366320 : known_function_manager *get_known_function_manager ()
160 : {
161 366320 : return &m_known_fn_mgr;
162 : }
163 :
164 : /* Dynamically-allocated region instances.
165 : The number of these within the analysis can grow arbitrarily.
166 : They are still owned by the manager. */
167 : const region *
168 : get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use);
169 : const region *create_region_for_alloca (const frame_region *frame);
170 :
171 : void log_stats (logger *logger, bool show_objs) const;
172 :
173 6611 : void begin_checking_feasibility (void) { m_checking_feasibility = true; }
174 6611 : void end_checking_feasibility (void) { m_checking_feasibility = false; }
175 :
176 382158 : logger *get_logger () const { return m_logger; }
177 :
178 : void dump_untracked_regions () const;
179 :
180 : const svalue *maybe_fold_binop (tree type, enum tree_code op,
181 : const svalue *arg0, const svalue *arg1);
182 : private:
183 : bool too_complex_p (const complexity &c) const;
184 : bool reject_if_too_complex (svalue *sval);
185 :
186 : const svalue *
187 : maybe_invert_comparison_in_unaryop (tree type,
188 : const binop_svalue *binop);
189 : const svalue *maybe_fold_unaryop (tree type, enum tree_code op,
190 : const svalue *arg);
191 : const svalue *maybe_fold_sub_svalue (tree type,
192 : const svalue *parent_svalue,
193 : const region *subregion);
194 : const svalue *maybe_fold_repeated_svalue (tree type,
195 : const svalue *outer_size,
196 : const svalue *inner_svalue);
197 : const svalue *maybe_fold_bits_within_svalue (tree type,
198 : const bit_range &bits,
199 : const svalue *inner_svalue);
200 : const svalue *maybe_undo_optimize_bit_field_compare (tree type,
201 : const compound_svalue *compound_sval,
202 : tree cst, const svalue *arg1);
203 : const svalue *maybe_fold_asm_output_svalue (tree type,
204 : const vec<const svalue *> &inputs);
205 :
206 : logger *m_logger;
207 :
208 : unsigned m_next_symbol_id;
209 :
210 : const call_string m_empty_call_string;
211 :
212 : root_region m_root_region;
213 : stack_region m_stack_region;
214 : heap_region m_heap_region;
215 :
216 : /* svalue consolidation. */
217 : typedef hash_map<constant_svalue::key_t, constant_svalue *> constants_map_t;
218 : constants_map_t m_constants_map;
219 :
220 : typedef hash_map<tree, unknown_svalue *> unknowns_map_t;
221 : unknowns_map_t m_unknowns_map;
222 : const unknown_svalue *m_unknown_NULL;
223 :
224 : typedef hash_map<poisoned_svalue::key_t,
225 : poisoned_svalue *> poisoned_values_map_t;
226 : poisoned_values_map_t m_poisoned_values_map;
227 :
228 : typedef hash_map<setjmp_svalue::key_t,
229 : setjmp_svalue *> setjmp_values_map_t;
230 : setjmp_values_map_t m_setjmp_values_map;
231 :
232 : typedef hash_map<const region *, initial_svalue *> initial_values_map_t;
233 : initial_values_map_t m_initial_values_map;
234 :
235 : typedef hash_map<region_svalue::key_t, region_svalue *> pointer_values_map_t;
236 : pointer_values_map_t m_pointer_values_map;
237 :
238 : typedef hash_map<unaryop_svalue::key_t,
239 : unaryop_svalue *> unaryop_values_map_t;
240 : unaryop_values_map_t m_unaryop_values_map;
241 :
242 : typedef hash_map<binop_svalue::key_t, binop_svalue *> binop_values_map_t;
243 : binop_values_map_t m_binop_values_map;
244 :
245 : typedef hash_map<sub_svalue::key_t, sub_svalue *> sub_values_map_t;
246 : sub_values_map_t m_sub_values_map;
247 :
248 : typedef hash_map<repeated_svalue::key_t,
249 : repeated_svalue *> repeated_values_map_t;
250 : repeated_values_map_t m_repeated_values_map;
251 :
252 : typedef hash_map<bits_within_svalue::key_t,
253 : bits_within_svalue *> bits_within_values_map_t;
254 : bits_within_values_map_t m_bits_within_values_map;
255 :
256 : typedef hash_map<const svalue *,
257 : unmergeable_svalue *> unmergeable_values_map_t;
258 : unmergeable_values_map_t m_unmergeable_values_map;
259 :
260 : typedef hash_map<widening_svalue::key_t,
261 : widening_svalue */*,
262 : widening_svalue::key_t::hash_map_traits*/>
263 : widening_values_map_t;
264 : widening_values_map_t m_widening_values_map;
265 :
266 : typedef hash_map<compound_svalue::key_t,
267 : compound_svalue *> compound_values_map_t;
268 : compound_values_map_t m_compound_values_map;
269 :
270 : typedef hash_map<conjured_svalue::key_t,
271 : conjured_svalue *> conjured_values_map_t;
272 : conjured_values_map_t m_conjured_values_map;
273 :
274 : typedef hash_map<asm_output_svalue::key_t,
275 : asm_output_svalue *> asm_output_values_map_t;
276 : asm_output_values_map_t m_asm_output_values_map;
277 :
278 : typedef hash_map<const_fn_result_svalue::key_t,
279 : const_fn_result_svalue *> const_fn_result_values_map_t;
280 : const_fn_result_values_map_t m_const_fn_result_values_map;
281 :
282 : bool m_checking_feasibility;
283 :
284 : /* "Dynamically-allocated" svalue instances.
285 : The number of these within the analysis can grow arbitrarily.
286 : They are still owned by the manager. */
287 : auto_delete_vec<svalue> m_managed_dynamic_svalues;
288 :
289 : /* Maximum complexity of svalues that weren't rejected. */
290 : complexity m_max_complexity;
291 :
292 : /* region consolidation. */
293 :
294 : code_region m_code_region;
295 : typedef hash_map<tree, function_region *> fndecls_map_t;
296 : typedef fndecls_map_t::iterator fndecls_iterator_t;
297 : fndecls_map_t m_fndecls_map;
298 :
299 : typedef hash_map<tree, label_region *> labels_map_t;
300 : typedef labels_map_t::iterator labels_iterator_t;
301 : labels_map_t m_labels_map;
302 :
303 : globals_region m_globals_region;
304 : typedef hash_map<tree, decl_region *> globals_map_t;
305 : typedef globals_map_t::iterator globals_iterator_t;
306 : globals_map_t m_globals_map;
307 :
308 : thread_local_region m_thread_local_region;
309 : errno_region m_errno_region;
310 :
311 : consolidation_map<field_region> m_field_regions;
312 : consolidation_map<element_region> m_element_regions;
313 : consolidation_map<offset_region> m_offset_regions;
314 : consolidation_map<sized_region> m_sized_regions;
315 : consolidation_map<cast_region> m_cast_regions;
316 : consolidation_map<frame_region> m_frame_regions;
317 : consolidation_map<symbolic_region> m_symbolic_regions;
318 :
319 : typedef hash_map<tree, string_region *> string_map_t;
320 : string_map_t m_string_map;
321 :
322 : consolidation_map<bit_range_region> m_bit_range_regions;
323 : consolidation_map<var_arg_region> m_var_arg_regions;
324 :
325 : store_manager m_store_mgr;
326 :
327 : bounded_ranges_manager *m_range_mgr;
328 :
329 : known_function_manager m_known_fn_mgr;
330 :
331 : /* "Dynamically-allocated" region instances.
332 : The number of these within the analysis can grow arbitrarily.
333 : They are still owned by the manager. */
334 : auto_delete_vec<region> m_managed_dynamic_regions;
335 : };
336 :
337 : } // namespace ana
338 :
339 : #endif /* GCC_ANALYZER_REGION_MODEL_MANAGER_H */
|