Line data Source code
1 : /* Classes for tracking pertinent events that happen along
2 : an execution path.
3 : Copyright (C) 2026 Free Software Foundation, Inc.
4 : Contributed by David Malcolm <dmalcolm@redhat.com>.
5 :
6 : This file is part of GCC.
7 :
8 : GCC is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3, or (at your option)
11 : any later version.
12 :
13 : GCC is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with GCC; see the file COPYING3. If not see
20 : <http://www.gnu.org/licenses/>. */
21 :
22 : #ifndef GCC_ANALYZER_STATE_TRANSITION_H
23 : #define GCC_ANALYZER_STATE_TRANSITION_H
24 :
25 : #include "diagnostics/event-id.h"
26 : #include "analyzer/callsite-expr.h"
27 :
28 : namespace ana {
29 :
30 : class state_transition
31 : {
32 : public:
33 : enum class kind
34 : {
35 : origin,
36 : at_call,
37 : at_return,
38 : copy,
39 : use
40 : };
41 :
42 79 : state_transition ()
43 79 : : m_prev_state_transition (nullptr)
44 : {
45 : }
46 :
47 : virtual ~state_transition () {}
48 :
49 : virtual std::unique_ptr<state_transition>
50 : clone () const = 0;
51 :
52 : virtual void
53 : dump_to_pp (pretty_printer *pp) const = 0;
54 :
55 : virtual enum kind get_kind () const = 0;
56 :
57 : virtual const state_transition_at_call *
58 0 : dyn_cast_state_transition_at_call () const { return nullptr; }
59 :
60 : virtual const state_transition_at_return *
61 0 : dyn_cast_state_transition_at_return () const { return nullptr; }
62 :
63 : void dump () const;
64 :
65 : static std::unique_ptr<state_transition>
66 : make (const region *src_reg,
67 : tree src_reg_expr,
68 : const region *dst_reg,
69 : tree dst_reg_expr);
70 :
71 : diagnostics::paths::event_id_t
72 : get_src_event_id () const;
73 :
74 : state_transition *m_prev_state_transition;
75 : diagnostics::paths::event_id_t m_event_id;
76 : };
77 :
78 : class state_transition_origin : public state_transition
79 : {
80 : public:
81 30 : state_transition_origin (tree dst_reg_expr)
82 30 : : m_dst_reg_expr (dst_reg_expr)
83 : {
84 : }
85 :
86 : std::unique_ptr<state_transition>
87 : clone () const final override;
88 :
89 : void
90 : dump_to_pp (pretty_printer *pp) const final override;
91 :
92 : enum kind
93 90 : get_kind () const final override { return kind::origin; }
94 :
95 : tree m_dst_reg_expr;
96 : };
97 :
98 : class state_transition_at_call : public state_transition
99 : {
100 : public:
101 23 : state_transition_at_call (callsite_expr expr)
102 23 : : m_expr (expr)
103 : {
104 : }
105 :
106 : std::unique_ptr<state_transition>
107 : clone () const final override;
108 :
109 : void
110 : dump_to_pp (pretty_printer *pp) const final override;
111 :
112 : enum kind
113 0 : get_kind () const final override { return kind::at_call; }
114 :
115 : const state_transition_at_call *
116 46 : dyn_cast_state_transition_at_call () const final override { return this; }
117 :
118 : callsite_expr
119 115 : get_callsite_expr () const { return m_expr; }
120 :
121 : private:
122 : callsite_expr m_expr;
123 : };
124 :
125 12 : class state_transition_at_return : public state_transition
126 : {
127 : public:
128 : std::unique_ptr<state_transition>
129 : clone () const final override;
130 :
131 : void
132 : dump_to_pp (pretty_printer *pp) const final override;
133 :
134 : enum kind
135 0 : get_kind () const final override { return kind::at_return; }
136 :
137 : const state_transition_at_return *
138 12 : dyn_cast_state_transition_at_return () const final override { return this; }
139 : };
140 :
141 : class state_transition_copy : public state_transition
142 : {
143 : public:
144 6 : state_transition_copy (tree src_reg_expr,
145 : tree dst_reg_expr)
146 6 : : m_src_reg_expr (src_reg_expr),
147 6 : m_dst_reg_expr (dst_reg_expr)
148 : {
149 6 : gcc_assert (m_src_reg_expr);
150 6 : gcc_assert (printable_expr_p (m_src_reg_expr));
151 :
152 6 : gcc_assert (m_dst_reg_expr);
153 6 : gcc_assert (printable_expr_p (m_dst_reg_expr));
154 6 : }
155 :
156 : std::unique_ptr<state_transition>
157 : clone () const final override;
158 :
159 : void
160 : dump_to_pp (pretty_printer *pp) const final override;
161 :
162 : enum kind
163 18 : get_kind () const final override { return kind::copy; }
164 :
165 : tree m_src_reg_expr;
166 : tree m_dst_reg_expr;
167 : };
168 :
169 : class state_transition_use : public state_transition
170 : {
171 : public:
172 8 : state_transition_use (tree src_reg_expr)
173 8 : : m_src_reg_expr (src_reg_expr)
174 : {
175 : }
176 :
177 : std::unique_ptr<state_transition>
178 : clone () const final override;
179 :
180 : void
181 : dump_to_pp (pretty_printer *pp) const final override;
182 :
183 : enum kind
184 24 : get_kind () const final override { return kind::use; }
185 :
186 : tree m_src_reg_expr;
187 : };
188 :
189 : } // namespace ana
190 :
191 : #endif /* GCC_ANALYZER_STATE_TRANSITION_H */
|