GCC Middle and Back End API Reference
program-state.h
Go to the documentation of this file.
1/* Classes for representing the state of interest at a given path of analysis.
2 Copyright (C) 2019-2025 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
24#include "text-art/widget.h"
26
27#include "analyzer/store.h"
28
29namespace ana {
30
31/* Data shared by all program_state instances. */
32
34{
35public:
36 extrinsic_state (std::vector<std::unique_ptr<state_machine>> &&checkers,
37 engine *eng,
38 logger *logger = nullptr)
39 : m_checkers (std::move (checkers)),
41 m_engine (eng)
42 {
43 }
44
45 // For use in selftests that use just one state machine
46 extrinsic_state (std::unique_ptr<state_machine> sm,
47 engine *eng,
48 logger *logger = nullptr)
49 : m_logger (logger),
50 m_engine (eng)
51 {
52 m_checkers.push_back (std::move (sm));
53 }
54
55 const state_machine &get_sm (int idx) const
56 {
57 return *m_checkers[idx];
58 }
59
60 const char *get_name (int idx) const
61 {
62 return m_checkers[idx]->get_name ();
63 }
64
65 unsigned get_num_checkers () const { return m_checkers.size (); }
66
67 logger *get_logger () const { return m_logger; }
68
69 void dump_to_pp (pretty_printer *pp) const;
70 void dump_to_file (FILE *outf) const;
71 void dump () const;
72
73 std::unique_ptr<json::object> to_json () const;
74
75 engine *get_engine () const { return m_engine; }
77
78 bool get_sm_idx_by_name (const char *name, unsigned *out) const;
79
80private:
81 /* The state machines. */
82 std::vector<std::unique_ptr<state_machine>> m_checkers;
83
86};
87
88/* Map from svalue * to state machine state, also capturing the origin of
89 each state. */
90
92{
93public:
94 /* An entry in the hash_map. */
95 struct entry_t
96 {
97 /* Default ctor needed by hash_map::empty. */
99 : m_state (0), m_origin (nullptr)
100 {
101 }
102
104 const svalue *origin)
105 : m_state (state), m_origin (origin)
106 {}
107
108 bool operator== (const entry_t &other) const
109 {
110 return (m_state == other.m_state
111 && m_origin == other.m_origin);
112 }
113 bool operator!= (const entry_t &other) const
114 {
115 return !(*this == other);
116 }
117
118 static int cmp (const entry_t &entry_a, const entry_t &entry_b);
119
122 };
123 typedef hash_map <const svalue *, entry_t> map_t;
124 typedef map_t::iterator iterator_t;
125
127
129
130 void print (const region_model *model,
131 bool simple, bool multiline,
132 pretty_printer *pp) const;
133 void dump (bool simple) const;
134
135 std::unique_ptr<json::object> to_json () const;
136
137 std::unique_ptr<text_art::tree_widget>
139 const region_model *model) const;
140
141 bool is_empty_p () const;
142
143 hashval_t hash () const;
144
145 bool operator== (const sm_state_map &other) const;
146 bool operator!= (const sm_state_map &other) const
147 {
148 return !(*this == other);
149 }
150
152 const extrinsic_state &ext_state) const;
153 const svalue *get_origin (const svalue *sval,
154 const extrinsic_state &ext_state) const;
155
157 const svalue *sval,
159 const svalue *origin,
161 bool set_state (const equiv_class &ec,
163 const svalue *origin,
165 bool impl_set_state (const svalue *sval,
167 const svalue *origin,
169 void clear_any_state (const svalue *sval);
171
174
175 void on_svalue_leak (const svalue *sval,
177 void on_liveness_change (const svalue_set &live_svalues,
178 const region_model *model,
181
182 void on_unknown_change (const svalue *sval,
183 bool is_mutable,
185
186 void purge_state_involving (const svalue *sval,
188
189 iterator_t begin () const { return m_map.begin (); }
190 iterator_t end () const { return m_map.end (); }
191 size_t elements () const { return m_map.elements (); }
192
193 static int cmp (const sm_state_map &smap_a, const sm_state_map &smap_b);
194
195 static const svalue *
197
199 const sm_state_map &summary);
200
201 bool can_merge_with_p (const sm_state_map &other,
202 const state_machine &sm,
204 sm_state_map **out) const;
205
206private:
210};
211
212/* A class for representing the state of interest at a given path of
213 analysis.
214
215 Currently this is a combination of:
216 (a) a region_model, giving:
217 (a.1) a hierarchy of memory regions
218 (a.2) values for the regions
219 (a.3) inequalities between values
220 (b) sm_state_maps per state machine, giving a sparse mapping of
221 values to states. */
222
224{
225public:
231
232 hashval_t hash () const;
233 bool operator== (const program_state &other) const;
234 bool operator!= (const program_state &other) const
235 {
236 return !(*this == other);
237 }
238
240 pretty_printer *pp) const;
241
242 void dump_to_pp (const extrinsic_state &ext_state, bool simple,
243 bool multiline, pretty_printer *pp) const;
244 void dump_to_file (const extrinsic_state &ext_state, bool simple,
245 bool multiline, FILE *outf) const;
246 void dump (const extrinsic_state &ext_state, bool simple) const;
247 void dump () const;
248
249 std::unique_ptr<diagnostics::digraphs::digraph>
251
252 void
254
255 void
257
258 std::unique_ptr<json::object>
260
261 std::unique_ptr<text_art::tree_widget>
263
264 void push_frame (const extrinsic_state &ext_state, const function &fun);
266
268 exploded_node *enode,
269 const gcall &call_stmt,
270 uncertainty_t *uncertainty);
271
273 exploded_node *enode,
274 const gcall &call_stmt,
275 uncertainty_t *uncertainty);
276
277
279 exploded_node *enode,
280 const superedge *succ,
281 uncertainty_t *uncertainty);
282
284 const program_point &point,
285 exploded_node *enode_for_diag,
286 uncertainty_t *uncertainty) const;
287
289
291 const svalue *sval) const
292 {
293 /* Don't purge vars that have non-purgeable sm state, to avoid
294 generating false "leak" complaints. */
295 int i;
296 sm_state_map *smap;
298 {
299 const state_machine &sm = ext_state.get_sm (i);
300 if (!sm.can_purge_p (smap->get_state (sval, ext_state)))
301 return false;
302 }
303 return true;
304 }
305
307 const region *base_reg) const;
308
309 bool can_merge_with_p (const program_state &other,
311 const program_point &point,
312 program_state *out) const;
313
314 void validate (const extrinsic_state &ext_state) const;
315
316 static void detect_leaks (const program_state &src_state,
317 const program_state &dest_state,
318 const svalue *extra_sval,
321
323 const program_state &summary);
324
328
329 /* TODO: lose the pointer here (const-correctness issues?). */
332
333 /* If false, then don't attempt to explore further states along this path.
334 For use in "handling" lvalues for tree codes we haven't yet
335 implemented. */
337};
338
339/* An abstract base class for use with for_each_state_change. */
340
342{
343public:
345
346 /* Return true for early exit, false to keep iterating. */
347 virtual bool on_global_state_change (const state_machine &sm,
348 state_machine::state_t src_sm_val,
349 state_machine::state_t dst_sm_val) = 0;
350
351 /* Return true for early exit, false to keep iterating. */
352 virtual bool on_state_change (const state_machine &sm,
353 state_machine::state_t src_sm_val,
354 state_machine::state_t dst_sm_val,
355 const svalue *dst_sval,
356 const svalue *dst_origin_sval) = 0;
357};
358
359extern bool for_each_state_change (const program_state &src_state,
360 const program_state &dst_state,
363
364} // namespace ana
365
366#endif /* GCC_ANALYZER_PROGRAM_STATE_H */
Definition call-summary.h:68
Definition region-model.h:1352
Definition constraint-manager.h:255
Definition exploded-graph.h:806
Definition exploded-graph.h:205
Definition program-state.h:34
void dump_to_file(FILE *outf) const
bool get_sm_idx_by_name(const char *name, unsigned *out) const
std::vector< std::unique_ptr< state_machine > > m_checkers
Definition program-state.h:82
unsigned get_num_checkers() const
Definition program-state.h:65
logger * get_logger() const
Definition program-state.h:67
std::unique_ptr< json::object > to_json() const
const char * get_name(int idx) const
Definition program-state.h:60
logger * m_logger
Definition program-state.h:84
void dump_to_pp(pretty_printer *pp) const
region_model_manager * get_model_manager() const
engine * m_engine
Definition program-state.h:85
extrinsic_state(std::vector< std::unique_ptr< state_machine > > &&checkers, engine *eng, logger *logger=nullptr)
Definition program-state.h:36
engine * get_engine() const
Definition program-state.h:75
const state_machine & get_sm(int idx) const
Definition program-state.h:55
extrinsic_state(std::unique_ptr< state_machine > sm, engine *eng, logger *logger=nullptr)
Definition program-state.h:46
Definition exploded-graph.h:39
Definition analyzer-logging.h:34
Definition program-point.h:175
Definition program-state.h:224
void returning_call(exploded_graph &eg, exploded_node *enode, const gcall &call_stmt, uncertainty_t *uncertainty)
bool can_purge_base_region_p(const extrinsic_state &ext_state, const region *base_reg) const
program_state prune_for_point(exploded_graph &eg, const program_point &point, exploded_node *enode_for_diag, uncertainty_t *uncertainty) const
void dump() const
std::unique_ptr< json::object > to_json(const extrinsic_state &ext_state) const
void dump(const extrinsic_state &ext_state, bool simple) const
bool operator!=(const program_state &other) const
Definition program-state.h:234
program_state(const program_state &other)
void push_frame(const extrinsic_state &ext_state, const function &fun)
void dump_dot(const extrinsic_state &ext_state) const
bool operator==(const program_state &other) const
static void detect_leaks(const program_state &src_state, const program_state &dest_state, const svalue *extra_sval, const extrinsic_state &ext_state, region_model_context *ctxt)
void dump_to_file(const extrinsic_state &ext_state, bool simple, bool multiline, FILE *outf) const
void print(const extrinsic_state &ext_state, pretty_printer *pp) const
bool replay_call_summary(call_summary_replay &r, const program_state &summary)
program_state & operator=(const program_state &other)
bool on_edge(exploded_graph &eg, exploded_node *enode, const superedge *succ, uncertainty_t *uncertainty)
program_state(program_state &&other)
void validate(const extrinsic_state &ext_state) const
auto_delete_vec< sm_state_map > m_checker_states
Definition program-state.h:331
std::unique_ptr< diagnostics::digraphs::digraph > make_diagnostic_state_graph(const extrinsic_state &ext_state) const
bool can_merge_with_p(const program_state &other, const extrinsic_state &ext_state, const program_point &point, program_state *out) const
region_model * m_region_model
Definition program-state.h:330
void push_call(exploded_graph &eg, exploded_node *enode, const gcall &call_stmt, uncertainty_t *uncertainty)
bool can_purge_p(const extrinsic_state &ext_state, const svalue *sval) const
Definition program-state.h:290
std::unique_ptr< text_art::tree_widget > make_dump_widget(const text_art::dump_widget_info &dwi) const
const function * get_current_function() const
tree get_representative_tree(const svalue *sval) const
hashval_t hash() const
void impl_call_analyzer_dump_state(const gcall &call, const extrinsic_state &ext_state, region_model_context *ctxt)
void dump_to_pp(const extrinsic_state &ext_state, bool simple, bool multiline, pretty_printer *pp) const
void dump_sarif(const extrinsic_state &ext_state) const
bool m_valid
Definition program-state.h:336
program_state(const extrinsic_state &ext_state)
Definition region-model.h:815
Definition region-model-manager.h:32
Definition region-model.h:298
Definition region.h:126
Definition program-state.h:92
map_t::iterator iterator_t
Definition program-state.h:124
bool operator==(const sm_state_map &other) const
bool can_merge_with_p(const sm_state_map &other, const state_machine &sm, const extrinsic_state &ext_state, sm_state_map **out) const
static const svalue * canonicalize_svalue(const svalue *sval, const extrinsic_state &ext_state)
static int cmp(const sm_state_map &smap_a, const sm_state_map &smap_b)
iterator_t begin() const
Definition program-state.h:189
state_machine::state_t m_global_state
Definition program-state.h:209
state_machine::state_t get_state(const svalue *sval, const extrinsic_state &ext_state) const
const state_machine & m_sm
Definition program-state.h:207
sm_state_map * clone() const
size_t elements() const
Definition program-state.h:191
hash_map< const svalue *, entry_t > map_t
Definition program-state.h:123
void print(const region_model *model, bool simple, bool multiline, pretty_printer *pp) const
map_t m_map
Definition program-state.h:208
std::unique_ptr< json::object > to_json() const
void set_state(region_model *model, const svalue *sval, state_machine::state_t state, const svalue *origin, const extrinsic_state &ext_state)
bool operator!=(const sm_state_map &other) const
Definition program-state.h:146
bool impl_set_state(const svalue *sval, state_machine::state_t state, const svalue *origin, const extrinsic_state &ext_state)
hashval_t hash() const
void clear_any_state(const svalue *sval)
void on_svalue_leak(const svalue *sval, impl_region_model_context *ctxt)
state_machine::state_t get_global_state() const
const svalue * get_origin(const svalue *sval, const extrinsic_state &ext_state) const
iterator_t end() const
Definition program-state.h:190
void on_unknown_change(const svalue *sval, bool is_mutable, const extrinsic_state &ext_state)
void clear_all_per_svalue_state()
void purge_state_involving(const svalue *sval, const extrinsic_state &ext_state)
bool set_state(const equiv_class &ec, state_machine::state_t state, const svalue *origin, const extrinsic_state &ext_state)
std::unique_ptr< text_art::tree_widget > make_dump_widget(const text_art::dump_widget_info &dwi, const region_model *model) const
void set_global_state(state_machine::state_t state)
bool is_empty_p() const
void on_liveness_change(const svalue_set &live_svalues, const region_model *model, const extrinsic_state &ext_state, impl_region_model_context *ctxt)
bool replay_call_summary(call_summary_replay &r, const sm_state_map &summary)
sm_state_map(const state_machine &sm)
void dump(bool simple) const
Definition program-state.h:342
virtual bool on_state_change(const state_machine &sm, state_machine::state_t src_sm_val, state_machine::state_t dst_sm_val, const svalue *dst_sval, const svalue *dst_origin_sval)=0
virtual ~state_change_visitor()
Definition program-state.h:344
virtual bool on_global_state_change(const state_machine &sm, state_machine::state_t src_sm_val, state_machine::state_t dst_sm_val)=0
Definition sm.h:41
const state_machine::state * state_t
Definition sm.h:61
virtual bool can_purge_p(state_t s) const =0
Definition supergraph.h:318
Definition svalue.h:92
Definition store.h:161
Definition region-model.h:222
Definition vec.h:1813
Definition ree.cc:583
Definition pretty-print.h:241
union tree_node * tree
Definition coretypes.h:97
Definition access-diagram.h:30
bool for_each_state_change(const program_state &src_state, const program_state &dst_state, const extrinsic_state &ext_state, state_change_visitor *visitor)
hash_set< const svalue * > svalue_set
Definition common.h:80
poly_int< N, C > r
Definition poly-int.h:774
i
Definition poly-int.h:776
static int cmp(const entry_t &entry_a, const entry_t &entry_b)
bool operator==(const entry_t &other) const
Definition program-state.h:108
entry_t(state_machine::state_t state, const svalue *origin)
Definition program-state.h:103
entry_t()
Definition program-state.h:98
state_machine::state_t m_state
Definition program-state.h:120
bool operator!=(const entry_t &other) const
Definition program-state.h:113
const svalue * m_origin
Definition program-state.h:121
Definition function.h:249
Definition gimple.h:352
Definition ira-emit.cc:158
Definition gengtype.h:377
Definition genautomata.cc:669
Definition dump-widget-info.h:31
#define FOR_EACH_VEC_ELT(V, I, P)
Definition vec.h:1895