]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/program-state.h
bpf: use xBPF signed div, mod insns when available
[thirdparty/gcc.git] / gcc / analyzer / program-state.h
CommitLineData
757bf1df
DM
1/* Classes for representing the state of interest at a given path of analysis.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_PROGRAM_STATE_H
22#define GCC_ANALYZER_PROGRAM_STATE_H
23
75038aa6
DM
24namespace ana {
25
757bf1df
DM
26/* Data shared by all program_state instances. */
27
28class extrinsic_state
29{
30public:
808f4dfe
DM
31 extrinsic_state (auto_delete_vec <state_machine> &checkers,
32 logger *logger = NULL,
33 engine *eng = NULL)
34 : m_checkers (checkers), m_logger (logger), m_engine (eng)
757bf1df
DM
35 {
36 }
37
38 const state_machine &get_sm (int idx) const
39 {
40 return *m_checkers[idx];
41 }
42
43 const char *get_name (int idx) const
44 {
45 return m_checkers[idx]->get_name ();
46 }
47
48 unsigned get_num_checkers () const { return m_checkers.length (); }
49
808f4dfe
DM
50 logger *get_logger () const { return m_logger; }
51
42f36563
DM
52 void dump_to_pp (pretty_printer *pp) const;
53 void dump_to_file (FILE *outf) const;
54 void dump () const;
55
808f4dfe
DM
56 engine *get_engine () const { return m_engine; }
57 region_model_manager *get_model_manager () const;
58
ebe9174e 59private:
757bf1df
DM
60 /* The state machines. */
61 auto_delete_vec <state_machine> &m_checkers;
757bf1df 62
808f4dfe
DM
63 logger *m_logger;
64 engine *m_engine;
757bf1df
DM
65};
66
808f4dfe 67/* Map from svalue * to state machine state, also capturing the origin of
757bf1df
DM
68 each state. */
69
70class sm_state_map
71{
72public:
73 /* An entry in the hash_map. */
74 struct entry_t
75 {
76 /* Default ctor needed by hash_map::empty. */
77 entry_t ()
808f4dfe 78 : m_state (0), m_origin (NULL)
757bf1df
DM
79 {
80 }
81
82 entry_t (state_machine::state_t state,
808f4dfe 83 const svalue *origin)
757bf1df
DM
84 : m_state (state), m_origin (origin)
85 {}
86
87 bool operator== (const entry_t &other) const
88 {
89 return (m_state == other.m_state
90 && m_origin == other.m_origin);
91 }
92 bool operator!= (const entry_t &other) const
93 {
94 return !(*this == other);
95 }
96
97 state_machine::state_t m_state;
808f4dfe 98 const svalue *m_origin;
757bf1df 99 };
808f4dfe 100 typedef hash_map <const svalue *, entry_t> map_t;
26d949c8 101 typedef map_t::iterator iterator_t;
757bf1df 102
808f4dfe 103 sm_state_map (const state_machine &sm, int m_sm_idx);
757bf1df
DM
104
105 sm_state_map *clone () const;
106
808f4dfe
DM
107 void print (const region_model *model,
108 bool simple, bool multiline,
41f99ba6 109 pretty_printer *pp) const;
808f4dfe 110 void dump (bool simple) const;
757bf1df
DM
111
112 bool is_empty_p () const;
113
114 hashval_t hash () const;
115
116 bool operator== (const sm_state_map &other) const;
117 bool operator!= (const sm_state_map &other) const
118 {
119 return !(*this == other);
120 }
121
808f4dfe
DM
122 state_machine::state_t get_state (const svalue *sval,
123 const extrinsic_state &ext_state) const;
124 const svalue *get_origin (const svalue *sval,
125 const extrinsic_state &ext_state) const;
757bf1df
DM
126
127 void set_state (region_model *model,
808f4dfe 128 const svalue *sval,
757bf1df 129 state_machine::state_t state,
808f4dfe
DM
130 const svalue *origin,
131 const extrinsic_state &ext_state);
d177c49c 132 bool set_state (const equiv_class &ec,
757bf1df 133 state_machine::state_t state,
808f4dfe
DM
134 const svalue *origin,
135 const extrinsic_state &ext_state);
136 bool impl_set_state (const svalue *sval,
757bf1df 137 state_machine::state_t state,
808f4dfe
DM
138 const svalue *origin,
139 const extrinsic_state &ext_state);
757bf1df
DM
140
141 void set_global_state (state_machine::state_t state);
142 state_machine::state_t get_global_state () const;
143
808f4dfe 144 void on_svalue_leak (const svalue *sval,
757bf1df 145 impl_region_model_context *ctxt);
808f4dfe
DM
146 void on_liveness_change (const svalue_set &live_svalues,
147 const region_model *model,
148 impl_region_model_context *ctxt);
757bf1df 149
808f4dfe
DM
150 void on_unknown_change (const svalue *sval,
151 bool is_mutable,
152 const extrinsic_state &ext_state);
757bf1df
DM
153
154 iterator_t begin () const { return m_map.begin (); }
155 iterator_t end () const { return m_map.end (); }
156
808f4dfe
DM
157 static const svalue *
158 canonicalize_svalue (const svalue *sval, const extrinsic_state &ext_state);
159
757bf1df 160private:
808f4dfe
DM
161 const state_machine &m_sm;
162 int m_sm_idx;
757bf1df
DM
163 map_t m_map;
164 state_machine::state_t m_global_state;
165};
166
167/* A class for representing the state of interest at a given path of
168 analysis.
169
170 Currently this is a combination of:
171 (a) a region_model, giving:
172 (a.1) a hierarchy of memory regions
173 (a.2) values for the regions
174 (a.3) inequalities between values
175 (b) sm_state_maps per state machine, giving a sparse mapping of
176 values to states. */
177
178class program_state
179{
180public:
181 program_state (const extrinsic_state &ext_state);
182 program_state (const program_state &other);
183 program_state& operator= (const program_state &other);
184
185#if __cplusplus >= 201103
186 program_state (program_state &&other);
757bf1df
DM
187#endif
188
189 ~program_state ();
190
191 hashval_t hash () const;
192 bool operator== (const program_state &other) const;
193 bool operator!= (const program_state &other) const
194 {
195 return !(*this == other);
196 }
197
198 void print (const extrinsic_state &ext_state,
199 pretty_printer *pp) const;
200
808f4dfe
DM
201 void dump_to_pp (const extrinsic_state &ext_state, bool simple,
202 bool multiline, pretty_printer *pp) const;
203 void dump_to_file (const extrinsic_state &ext_state, bool simple,
204 bool multiline, FILE *outf) const;
205 void dump (const extrinsic_state &ext_state, bool simple) const;
206
207 void push_frame (const extrinsic_state &ext_state, function *fun);
208 function * get_current_function () const;
757bf1df
DM
209
210 bool on_edge (exploded_graph &eg,
211 const exploded_node &enode,
808f4dfe 212 const superedge *succ);
757bf1df
DM
213
214 program_state prune_for_point (exploded_graph &eg,
215 const program_point &point,
808f4dfe 216 const exploded_node *enode_for_diag) const;
757bf1df 217
808f4dfe 218 tree get_representative_tree (const svalue *sval) const;
757bf1df
DM
219
220 bool can_purge_p (const extrinsic_state &ext_state,
808f4dfe 221 const svalue *sval)
757bf1df
DM
222 {
223 /* Don't purge vars that have non-purgeable sm state, to avoid
224 generating false "leak" complaints. */
225 int i;
226 sm_state_map *smap;
227 FOR_EACH_VEC_ELT (m_checker_states, i, smap)
228 {
229 const state_machine &sm = ext_state.get_sm (i);
808f4dfe 230 if (!sm.can_purge_p (smap->get_state (sval, ext_state)))
757bf1df
DM
231 return false;
232 }
233 return true;
234 }
235
236 bool can_merge_with_p (const program_state &other,
808f4dfe 237 const program_point &point,
757bf1df
DM
238 program_state *out) const;
239
240 void validate (const extrinsic_state &ext_state) const;
241
808f4dfe
DM
242 static void detect_leaks (const program_state &src_state,
243 const program_state &dest_state,
244 const svalue *extra_sval,
245 const extrinsic_state &ext_state,
246 region_model_context *ctxt);
247
757bf1df
DM
248 /* TODO: lose the pointer here (const-correctness issues?). */
249 region_model *m_region_model;
250 auto_delete_vec<sm_state_map> m_checker_states;
f76a88eb
DM
251
252 /* If false, then don't attempt to explore further states along this path.
253 For use in "handling" lvalues for tree codes we haven't yet
254 implemented. */
255 bool m_valid;
757bf1df
DM
256};
257
258/* An abstract base class for use with for_each_state_change. */
259
260class state_change_visitor
261{
262public:
263 virtual ~state_change_visitor () {}
264
265 /* Return true for early exit, false to keep iterating. */
266 virtual bool on_global_state_change (const state_machine &sm,
267 state_machine::state_t src_sm_val,
268 state_machine::state_t dst_sm_val) = 0;
269
270 /* Return true for early exit, false to keep iterating. */
271 virtual bool on_state_change (const state_machine &sm,
272 state_machine::state_t src_sm_val,
273 state_machine::state_t dst_sm_val,
808f4dfe
DM
274 const svalue *dst_sval,
275 const svalue *dst_origin_sval) = 0;
757bf1df
DM
276};
277
278extern bool for_each_state_change (const program_state &src_state,
808f4dfe
DM
279 const program_state &dst_state,
280 const extrinsic_state &ext_state,
281 state_change_visitor *visitor);
757bf1df 282
75038aa6
DM
283} // namespace ana
284
757bf1df 285#endif /* GCC_ANALYZER_PROGRAM_STATE_H */