GCC Middle and Back End API Reference
sm.h
Go to the documentation of this file.
1/* Modeling API uses and misuses via state machines.
2 Copyright (C) 2019-2026 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_SM_H
22#define GCC_ANALYZER_SM_H
23
25
26/* Utility functions for use by state machines. */
27
28namespace ana {
29
30class state_machine;
31class sm_context;
34
35extern bool any_pointer_p (tree expr);
36extern bool any_pointer_p (const svalue *sval);
37
38/* An abstract base class for a state machine describing an API.
39 Manages a set of state objects, and has various virtual functions
40 for pattern-matching on statements. */
41
42class state_machine : public log_user
43{
44public:
45 /* States are represented by immutable objects, owned by the state
46 machine. */
47 class state
48 {
49 public:
50 state (const char *name, unsigned id) : m_name (name), m_id (id) {}
51 virtual ~state () {}
52
53 const char *get_name () const { return m_name; }
54 virtual void dump_to_pp (pretty_printer *pp) const;
55 virtual std::unique_ptr<json::value> to_json () const;
56
57 unsigned get_id () const { return m_id; }
58
59 private:
60 const char *m_name;
61 unsigned m_id;
62 };
64
65 state_machine (const char *name, logger *logger);
66 virtual ~state_machine () {}
67
68 /* Should states be inherited from a parent region to a child region,
69 when first accessing a child region?
70 For example we should inherit the taintedness of a subregion,
71 but we should not inherit the "malloc:non-null" state of a field
72 within a heap-allocated struct. */
73 virtual bool inherited_state_p () const = 0;
74
75 /* A vfunc for more general handling of inheritance. */
76 virtual state_t
78 const svalue *,
79 const extrinsic_state &) const
80 {
81 return nullptr;
82 }
83
84 virtual bool
86 {
87 return false;
88 }
89
91 {
92 return m_start;
93 }
94
95 const char *get_name () const { return m_name; }
96
97 state_t get_state_by_name (const char *name) const;
98
99 /* Return true if STMT is a function call recognized by this sm. */
100 virtual bool on_stmt (sm_context &sm_ctxt,
101 const gimple *stmt) const = 0;
102
103 virtual void on_phi (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
104 const gphi *phi ATTRIBUTE_UNUSED,
105 tree rhs ATTRIBUTE_UNUSED) const
106 {
107 }
108
109 virtual void
110 check_call_preconditions (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
111 const call_details &cd ATTRIBUTE_UNUSED) const
112 {
113 }
114
115 virtual void on_condition (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
116 const svalue *lhs ATTRIBUTE_UNUSED,
117 enum tree_code op ATTRIBUTE_UNUSED,
118 const svalue *rhs ATTRIBUTE_UNUSED) const
119 {
120 }
121
122 virtual void
123 on_bounded_ranges (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
124 const svalue &sval ATTRIBUTE_UNUSED,
125 const bounded_ranges &ranges ATTRIBUTE_UNUSED) const
126 {
127 }
128
129 virtual void
130 on_pop_frame (sm_state_map *smap ATTRIBUTE_UNUSED,
131 const frame_region *frame_reg ATTRIBUTE_UNUSED) const
132 {
133 }
134
135 /* Return true if it safe to discard the given state (to help
136 when simplifying state objects).
137 States that need leak detection should return false. */
138 virtual bool can_purge_p (state_t s) const = 0;
139
140 /* Called when VAR leaks (and !can_purge_p). */
141 virtual std::unique_ptr<pending_diagnostic>
142 on_leak (tree var ATTRIBUTE_UNUSED,
143 const program_state *old_state,
144 const program_state *new_state) const;
145
146 /* Return true if S should be reset to "start" for values passed (or reachable
147 from) calls to unknown functions. IS_MUTABLE is true for pointers as
148 non-const, false if only passed as const-pointers.
149
150 For example, in sm-malloc.cc, an on-stack ptr doesn't stop being
151 stack-allocated when passed to an unknown fn, but a malloc-ed pointer
152 could be freed when passed to an unknown fn (unless passed as "const"). */
153 virtual bool reset_when_passed_to_unknown_fn_p (state_t s ATTRIBUTE_UNUSED,
154 bool is_mutable) const
155 {
156 return is_mutable;
157 }
158
159 /* Attempt to get a state for the merger of STATE_A and STATE_B,
160 or return nullptr if merging shouldn't occur, so that differences
161 between sm-state will lead to separate exploded nodes.
162
163 Most state machines will only merge equal states, but can
164 override maybe_get_merged_states_nonequal to support mergers
165 of certain non-equal states. */
167 state_t state_b) const
168 {
169 if (state_a == state_b)
170 return state_a;
171 return maybe_get_merged_states_nonequal (state_a, state_b);
172 }
173
174 /* Base implementation of hook for maybe_get_merged_state on non-equal
175 states. */
176 virtual state_t
177 maybe_get_merged_states_nonequal (state_t state_a ATTRIBUTE_UNUSED,
178 state_t state_b ATTRIBUTE_UNUSED) const
179 {
180 /* By default, non-equal sm states should inhibit merger of enodes. */
181 return nullptr;
182 }
183
184 void validate (state_t s) const;
185
186 void dump_to_pp (pretty_printer *pp) const;
187
188 std::unique_ptr<json::object> to_json () const;
189
190 state_t get_start_state () const { return m_start; }
191
192 virtual void
194 const svalue &sval,
196
197 virtual void
200
201protected:
202 state_t add_state (const char *name);
204 {
205 m_states.safe_push (s);
206 return s;
207 }
208
209 unsigned alloc_state_id () { return m_next_state_id++; }
210
211private:
213
214 const char *m_name;
215
216 /* States are owned by the state_machine. */
218
220
221protected:
222 /* Must be inited after m_next_state_id. */
224};
225
226/* Abstract base class for state machines to pass to
227 sm_context::on_custom_transition for handling non-standard transitions
228 (e.g. adding a node and edge to simulate registering a callback and having
229 the callback be called later). */
230
232{
233public:
234 virtual ~custom_transition () {}
236 exploded_node *src_enode,
237 int sm_idx) = 0;
238};
239
240/* Abstract base class giving an interface for the state machine to call
241 the checker engine, at a particular code location. */
242
244{
245public:
246 virtual ~sm_context () {}
247
248 /* Get the fndecl used at call, or NULL_TREE.
249 Use in preference to gimple_call_fndecl (and gimple_call_addr_fndecl),
250 since it can look through function pointer assignments and
251 other callback handling. */
252 virtual tree get_fndecl_for_call (const gcall &call) = 0;
253
254 /* Get the old state of VAR. */
257
258 /* Set the next state of VAR to be TO, recording the "origin" of the
259 state as ORIGIN. */
260 virtual void set_next_state (tree var,
262 tree origin = NULL_TREE) = 0;
263 virtual void set_next_state (const svalue *var,
265 tree origin = NULL_TREE) = 0;
266
267 /* Called by state_machine in response to pattern matches:
268 if VAR is in state FROM, transition it to state TO, potentially
269 recording the "origin" of the state as ORIGIN. */
273 tree origin = NULL_TREE)
274 {
275 state_machine::state_t current = get_state (var);
276 if (current == from)
277 set_next_state (var, to, origin);
278 }
279
280 void on_transition (const svalue *var,
283 tree origin = NULL_TREE)
284 {
285 state_machine::state_t current = get_state (var);
286 if (current == from)
287 set_next_state (var, to, origin);
288 }
289
290 /* Called by state_machine in response to pattern matches:
291 issue a diagnostic D about VAR. */
292 virtual void warn (tree var,
293 std::unique_ptr<pending_diagnostic> d) = 0;
294 virtual void warn (const svalue *var,
295 std::unique_ptr<pending_diagnostic> d) = 0;
296
297 /* For use when generating trees when creating pending_diagnostics, so that
298 rather than e.g.
299 "double-free of '<unknown>'"
300 we can print:
301 "double-free of 'inbuf.data'". */
303 {
304 return expr;
305 }
306 virtual tree get_diagnostic_tree (const svalue *) = 0;
307
310
311 virtual void clear_all_per_svalue_state () = 0;
312
313 /* A vfunc for handling custom transitions, such as when registering
314 a signal handler. */
316
317 /* If STMT is an assignment known to assign zero to its LHS, return
318 the LHS.
319 Otherwise return NULL_TREE. */
320 virtual tree is_zero_assignment (const gimple *stmt) = 0;
321
323 {
324 return nullptr;
325 }
326
327 /* Are we handling an external function with unknown side effects? */
328 virtual bool unknown_side_effects_p () const { return false; }
329
330 virtual const program_state *get_old_program_state () const = 0;
331 virtual const program_state *get_new_program_state () const = 0;
332
334
335 /* Get the location a diagnostic would be emitted at. */
336 virtual location_t get_emission_location () const = 0;
337
338protected:
339 sm_context (int sm_idx, const state_machine &sm)
340 : m_sm_idx (sm_idx), m_sm (sm) {}
341
344};
345
346
347/* The various state_machine subclasses are hidden in their respective
348 implementation files. */
349
350extern std::vector<std::unique_ptr<state_machine>>
352
353extern std::unique_ptr<state_machine> make_malloc_state_machine (logger *);
354extern std::unique_ptr<state_machine> make_fileptr_state_machine (logger *);
355extern std::unique_ptr<state_machine> make_taint_state_machine (logger *);
356extern std::unique_ptr<state_machine> make_sensitive_state_machine (logger *);
357extern std::unique_ptr<state_machine> make_signal_state_machine (logger *);
358extern std::unique_ptr<state_machine> make_pattern_test_state_machine (logger *);
359extern std::unique_ptr<state_machine> make_va_list_state_machine (logger *);
360extern std::unique_ptr<state_machine> make_fd_state_machine (logger *);
361
362} // namespace ana
363
364#endif /* GCC_ANALYZER_SM_H */
Definition ana-state-to-diagnostic-state.h:33
Definition call-details.h:31
Definition sm.h:232
virtual void impl_transition(exploded_graph *eg, exploded_node *src_enode, int sm_idx)=0
virtual ~custom_transition()
Definition sm.h:234
Definition exploded-graph.h:783
Definition exploded-graph.h:206
Definition program-state.h:34
Definition region.h:319
log_user(logger *logger)
Definition analyzer-logging.h:34
Definition common.h:435
Definition pending-diagnostic.h:189
Definition program-state.h:224
Definition region-model.h:299
Definition sm.h:244
virtual void set_next_state(tree var, state_machine::state_t to, tree origin=NULL_TREE)=0
const state_machine & m_sm
Definition sm.h:343
void on_transition(const svalue *var, state_machine::state_t from, state_machine::state_t to, tree origin=NULL_TREE)
Definition sm.h:280
virtual state_machine::state_t get_state(const svalue *)=0
virtual tree get_diagnostic_tree(tree expr)
Definition sm.h:302
virtual void warn(const svalue *var, std::unique_ptr< pending_diagnostic > d)=0
virtual void set_global_state(state_machine::state_t)=0
virtual location_t get_emission_location() const =0
virtual void set_next_state(const svalue *var, state_machine::state_t to, tree origin=NULL_TREE)=0
virtual const program_state * get_old_program_state() const =0
virtual ~sm_context()
Definition sm.h:246
virtual state_machine::state_t get_global_state() const =0
virtual tree is_zero_assignment(const gimple *stmt)=0
virtual void clear_all_per_svalue_state()=0
virtual state_machine::state_t get_state(tree var)=0
virtual void warn(tree var, std::unique_ptr< pending_diagnostic > d)=0
virtual const program_state * get_new_program_state() const =0
const region_model * get_old_region_model() const
void on_transition(tree var, state_machine::state_t from, state_machine::state_t to, tree origin=NULL_TREE)
Definition sm.h:270
virtual path_context * get_path_context() const
Definition sm.h:322
int m_sm_idx
Definition sm.h:342
virtual bool unknown_side_effects_p() const
Definition sm.h:328
sm_context(int sm_idx, const state_machine &sm)
Definition sm.h:339
virtual tree get_diagnostic_tree(const svalue *)=0
virtual tree get_fndecl_for_call(const gcall &call)=0
virtual void on_custom_transition(custom_transition *transition)=0
Definition program-state.h:92
Definition sm.h:48
virtual void dump_to_pp(pretty_printer *pp) const
unsigned m_id
Definition sm.h:61
virtual std::unique_ptr< json::value > to_json() const
unsigned get_id() const
Definition sm.h:57
state(const char *name, unsigned id)
Definition sm.h:50
virtual ~state()
Definition sm.h:51
const char * m_name
Definition sm.h:60
const char * get_name() const
Definition sm.h:53
Definition sm.h:43
const char * get_name() const
Definition sm.h:95
virtual state_t maybe_get_merged_states_nonequal(state_t state_a, state_t state_b) const
Definition sm.h:177
void validate(state_t s) const
virtual ~state_machine()
Definition sm.h:66
virtual bool inherited_state_p() const =0
virtual state_machine::state_t get_default_state(const svalue *) const
Definition sm.h:90
auto_delete_vec< state > m_states
Definition sm.h:217
state_t maybe_get_merged_state(state_t state_a, state_t state_b) const
Definition sm.h:166
virtual void check_call_preconditions(sm_context &sm_ctxt, const call_details &cd) const
Definition sm.h:110
virtual bool reset_when_passed_to_unknown_fn_p(state_t s, bool is_mutable) const
Definition sm.h:153
state_t add_custom_state(state *s)
Definition sm.h:203
virtual void on_pop_frame(sm_state_map *smap, const frame_region *frame_reg) const
Definition sm.h:130
unsigned m_next_state_id
Definition sm.h:219
state_t get_start_state() const
Definition sm.h:190
const char * m_name
Definition sm.h:214
state_machine(const char *name, logger *logger)
virtual void on_condition(sm_context &sm_ctxt, const svalue *lhs, enum tree_code op, const svalue *rhs) const
Definition sm.h:115
std::unique_ptr< json::object > to_json() const
virtual void add_global_state_to_state_graph(analyzer_state_graph &out_state_graph, state_machine::state_t state) const
virtual bool has_alt_get_inherited_state_p() const
Definition sm.h:85
virtual state_t alt_get_inherited_state(const sm_state_map &, const svalue *, const extrinsic_state &) const
Definition sm.h:77
const state_machine::state * state_t
Definition sm.h:63
virtual std::unique_ptr< pending_diagnostic > on_leak(tree var, const program_state *old_state, const program_state *new_state) const
void dump_to_pp(pretty_printer *pp) const
virtual void on_bounded_ranges(sm_context &sm_ctxt, const svalue &sval, const bounded_ranges &ranges) const
Definition sm.h:123
virtual bool on_stmt(sm_context &sm_ctxt, const gimple *stmt) const =0
virtual void on_phi(sm_context &sm_ctxt, const gphi *phi, tree rhs) const
Definition sm.h:103
unsigned alloc_state_id()
Definition sm.h:209
state_t get_state_by_name(const char *name) const
state_t m_start
Definition sm.h:223
virtual void add_state_to_state_graph(analyzer_state_graph &out_state_graph, const svalue &sval, state_machine::state_t state) const
DISABLE_COPY_AND_ASSIGN(state_machine)
state_t add_state(const char *name)
virtual bool can_purge_p(state_t s) const =0
Definition svalue.h:92
Definition vec.h:1813
Definition genmatch.cc:1506
Definition pretty-print.h:241
Definition genrecog.cc:1504
union tree_node * tree
Definition coretypes.h:97
struct state * state_t
Definition genautomata.cc:195
tree_code
Definition genmatch.cc:1002
Definition access-diagram.h:30
std::unique_ptr< state_machine > make_signal_state_machine(logger *)
@ stmt
Definition checker-event.h:38
std::unique_ptr< state_machine > make_taint_state_machine(logger *)
std::unique_ptr< state_machine > make_sensitive_state_machine(logger *)
std::unique_ptr< state_machine > make_pattern_test_state_machine(logger *)
std::unique_ptr< state_machine > make_va_list_state_machine(logger *)
std::unique_ptr< state_machine > make_fileptr_state_machine(logger *)
std::vector< std::unique_ptr< state_machine > > make_checkers(logger *logger)
std::unique_ptr< state_machine > make_malloc_state_machine(logger *)
bool any_pointer_p(tree expr)
std::unique_ptr< state_machine > make_fd_state_machine(logger *)
Definition constraint-manager.h:123
Definition gimple.h:352
Definition gimple.h:221
Definition gimple.h:461
Definition collect2.cc:168
static control_dependences * cd
Definition tree-ssa-dce.cc:104
#define NULL_TREE
Definition tree.h:318