aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/region-model-manager.h
blob: 0ff253b624cd838b4830f3f7e02ce5626bbcde5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/* Consolidation of svalues and regions.
   Copyright (C) 2020-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_ANALYZER_REGION_MODEL_MANAGER_H
#define GCC_ANALYZER_REGION_MODEL_MANAGER_H

namespace ana {

/* A class responsible for owning and consolidating region and svalue
   instances.
   region and svalue instances are immutable as far as clients are
   concerned, so they are provided as "const" ptrs.  */

class region_model_manager
{
public:
  region_model_manager (logger *logger = NULL);
  ~region_model_manager ();

  /* call_string consolidation.  */
  const call_string &get_empty_call_string () const
  {
    return m_empty_call_string;
  }

  /* svalue consolidation.  */
  const svalue *get_or_create_constant_svalue (tree cst_expr);
  const svalue *get_or_create_int_cst (tree type, poly_int64);
  const svalue *get_or_create_unknown_svalue (tree type);
  const svalue *get_or_create_setjmp_svalue (const setjmp_record &r,
					     tree type);
  const svalue *get_or_create_poisoned_svalue (enum poison_kind kind,
					       tree type);
  const svalue *get_or_create_initial_value (const region *reg);
  const svalue *get_ptr_svalue (tree ptr_type, const region *pointee);
  const svalue *get_or_create_unaryop (tree type, enum tree_code op,
				       const svalue *arg);
  const svalue *get_or_create_cast (tree type, const svalue *arg);
  const svalue *get_or_create_binop (tree type,
				     enum tree_code op,
				     const svalue *arg0, const svalue *arg1);
  const svalue *get_or_create_sub_svalue (tree type,
					  const svalue *parent_svalue,
					  const region *subregion);
  const svalue *get_or_create_repeated_svalue (tree type,
					       const svalue *outer_size,
					       const svalue *inner_svalue);
  const svalue *get_or_create_bits_within (tree type,
					   const bit_range &bits,
					   const svalue *inner_svalue);
  const svalue *get_or_create_unmergeable (const svalue *arg);
  const svalue *get_or_create_widening_svalue (tree type,
					       const function_point &point,
					       const svalue *base_svalue,
					       const svalue *iter_svalue);
  const svalue *get_or_create_compound_svalue (tree type,
					       const binding_map &map);
  const svalue *get_or_create_conjured_svalue (tree type, const gimple *stmt,
					       const region *id_reg,
					       const conjured_purge &p);
  const svalue *
  get_or_create_asm_output_svalue (tree type,
				   const gasm *asm_stmt,
				   unsigned output_idx,
				   const vec<const svalue *> &inputs);
  const svalue *
  get_or_create_asm_output_svalue (tree type,
				   const char *asm_string,
				   unsigned output_idx,
				   unsigned num_outputs,
				   const vec<const svalue *> &inputs);
  const svalue *
  get_or_create_const_fn_result_svalue (tree type,
					tree fndecl,
					const vec<const svalue *> &inputs);

  const svalue *maybe_get_char_from_string_cst (tree string_cst,
						tree byte_offset_cst);

  /* Dynamically-allocated svalue instances.
     The number of these within the analysis can grow arbitrarily.
     They are still owned by the manager.  */
  const svalue *create_unique_svalue (tree type);

  /* region consolidation.  */
  const stack_region * get_stack_region () const { return &m_stack_region; }
  const heap_region *get_heap_region () const { return &m_heap_region; }
  const code_region *get_code_region () const { return &m_code_region; }
  const globals_region *get_globals_region () const
  {
    return &m_globals_region;
  }
  const errno_region *get_errno_region () const { return &m_errno_region; }
  const function_region *get_region_for_fndecl (tree fndecl);
  const label_region *get_region_for_label (tree label);
  const decl_region *get_region_for_global (tree expr);
  const region *get_field_region (const region *parent, tree field);
  const region *get_element_region (const region *parent,
				    tree element_type,
				    const svalue *index);
  const region *get_offset_region (const region *parent,
				   tree type,
				   const svalue *byte_offset);
  const region *get_sized_region (const region *parent,
				  tree type,
				  const svalue *byte_size_sval);
  const region *get_cast_region (const region *original_region,
				 tree type);
  const frame_region *get_frame_region (const frame_region *calling_frame,
					function *fun);
  const region *get_symbolic_region (const svalue *sval);
  const string_region *get_region_for_string (tree string_cst);
  const region *get_bit_range (const region *parent, tree type,
			       const bit_range &bits);
  const var_arg_region *get_var_arg_region (const frame_region *parent,
					    unsigned idx);

  const region *get_unknown_symbolic_region (tree region_type);

  const region *
  get_region_for_unexpected_tree_code (region_model_context *ctxt,
				       tree t,
				       const dump_location_t &loc);

  unsigned alloc_region_id () { return m_next_region_id++; }

  store_manager *get_store_manager () { return &m_store_mgr; }
  bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }

  known_function_manager *get_known_function_manager ()
  {
    return &m_known_fn_mgr;
  }

  /* Dynamically-allocated region instances.
     The number of these within the analysis can grow arbitrarily.
     They are still owned by the manager.  */
  const region *create_region_for_heap_alloc ();
  const region *create_region_for_alloca (const frame_region *frame);

  void log_stats (logger *logger, bool show_objs) const;

  void begin_checking_feasibility (void) { m_checking_feasibility = true; }
  void end_checking_feasibility (void) { m_checking_feasibility = false; }

  logger *get_logger () const { return m_logger; }

  void dump_untracked_regions () const;

private:
  bool too_complex_p (const complexity &c) const;
  bool reject_if_too_complex (svalue *sval);

  const svalue *maybe_fold_unaryop (tree type, enum tree_code op,
				    const svalue *arg);
  const svalue *maybe_fold_binop (tree type, enum tree_code op,
				  const svalue *arg0, const svalue *arg1);
  const svalue *maybe_fold_sub_svalue (tree type,
				       const svalue *parent_svalue,
				       const region *subregion);
  const svalue *maybe_fold_repeated_svalue (tree type,
					    const svalue *outer_size,
					    const svalue *inner_svalue);
  const svalue *maybe_fold_bits_within_svalue (tree type,
					       const bit_range &bits,
					       const svalue *inner_svalue);
  const svalue *maybe_undo_optimize_bit_field_compare (tree type,
						       const compound_svalue *compound_sval,
						       tree cst, const svalue *arg1);
  const svalue *maybe_fold_asm_output_svalue (tree type,
					      const vec<const svalue *> &inputs);

  logger *m_logger;

  const call_string m_empty_call_string;

  unsigned m_next_region_id;
  root_region m_root_region;
  stack_region m_stack_region;
  heap_region m_heap_region;

  /* svalue consolidation.  */
  typedef hash_map<tree, constant_svalue *> constants_map_t;
  constants_map_t m_constants_map;

  typedef hash_map<tree, unknown_svalue *> unknowns_map_t;
  unknowns_map_t m_unknowns_map;
  const unknown_svalue *m_unknown_NULL;

  typedef hash_map<poisoned_svalue::key_t,
		   poisoned_svalue *> poisoned_values_map_t;
  poisoned_values_map_t m_poisoned_values_map;

  typedef hash_map<setjmp_svalue::key_t,
		   setjmp_svalue *> setjmp_values_map_t;
  setjmp_values_map_t m_setjmp_values_map;

  typedef hash_map<const region *, initial_svalue *> initial_values_map_t;
  initial_values_map_t m_initial_values_map;

  typedef hash_map<region_svalue::key_t, region_svalue *> pointer_values_map_t;
  pointer_values_map_t m_pointer_values_map;

  typedef hash_map<unaryop_svalue::key_t,
		   unaryop_svalue *> unaryop_values_map_t;
  unaryop_values_map_t m_unaryop_values_map;

  typedef hash_map<binop_svalue::key_t, binop_svalue *> binop_values_map_t;
  binop_values_map_t m_binop_values_map;

  typedef hash_map<sub_svalue::key_t, sub_svalue *> sub_values_map_t;
  sub_values_map_t m_sub_values_map;

  typedef hash_map<repeated_svalue::key_t,
		   repeated_svalue *> repeated_values_map_t;
  repeated_values_map_t m_repeated_values_map;

  typedef hash_map<bits_within_svalue::key_t,
		   bits_within_svalue *> bits_within_values_map_t;
  bits_within_values_map_t m_bits_within_values_map;

  typedef hash_map<const svalue *,
		   unmergeable_svalue *> unmergeable_values_map_t;
  unmergeable_values_map_t m_unmergeable_values_map;

  typedef hash_map<widening_svalue::key_t,
		   widening_svalue */*,
		   widening_svalue::key_t::hash_map_traits*/>
    widening_values_map_t;
  widening_values_map_t m_widening_values_map;

  typedef hash_map<compound_svalue::key_t,
		   compound_svalue *> compound_values_map_t;
  compound_values_map_t m_compound_values_map;

  typedef hash_map<conjured_svalue::key_t,
		   conjured_svalue *> conjured_values_map_t;
  conjured_values_map_t m_conjured_values_map;

  typedef hash_map<asm_output_svalue::key_t,
		   asm_output_svalue *> asm_output_values_map_t;
  asm_output_values_map_t m_asm_output_values_map;

  typedef hash_map<const_fn_result_svalue::key_t,
		   const_fn_result_svalue *> const_fn_result_values_map_t;
  const_fn_result_values_map_t m_const_fn_result_values_map;

  bool m_checking_feasibility;

  /* "Dynamically-allocated" svalue instances.
     The number of these within the analysis can grow arbitrarily.
     They are still owned by the manager.  */
  auto_delete_vec<svalue> m_managed_dynamic_svalues;

  /* Maximum complexity of svalues that weren't rejected.  */
  complexity m_max_complexity;

  /* region consolidation.  */

  code_region m_code_region;
  typedef hash_map<tree, function_region *> fndecls_map_t;
  typedef fndecls_map_t::iterator fndecls_iterator_t;
  fndecls_map_t m_fndecls_map;

  typedef hash_map<tree, label_region *> labels_map_t;
  typedef labels_map_t::iterator labels_iterator_t;
  labels_map_t m_labels_map;

  globals_region m_globals_region;
  typedef hash_map<tree, decl_region *> globals_map_t;
  typedef globals_map_t::iterator globals_iterator_t;
  globals_map_t m_globals_map;

  thread_local_region m_thread_local_region;
  errno_region m_errno_region;

  consolidation_map<field_region> m_field_regions;
  consolidation_map<element_region> m_element_regions;
  consolidation_map<offset_region> m_offset_regions;
  consolidation_map<sized_region> m_sized_regions;
  consolidation_map<cast_region> m_cast_regions;
  consolidation_map<frame_region> m_frame_regions;
  consolidation_map<symbolic_region> m_symbolic_regions;

  typedef hash_map<tree, string_region *> string_map_t;
  string_map_t m_string_map;

  consolidation_map<bit_range_region> m_bit_range_regions;
  consolidation_map<var_arg_region> m_var_arg_regions;

  store_manager m_store_mgr;

  bounded_ranges_manager *m_range_mgr;

  known_function_manager m_known_fn_mgr;

  /* "Dynamically-allocated" region instances.
     The number of these within the analysis can grow arbitrarily.
     They are still owned by the manager.  */
  auto_delete_vec<region> m_managed_dynamic_regions;
};

} // namespace ana

#endif /* GCC_ANALYZER_REGION_MODEL_MANAGER_H */