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 : #include "analyzer/common.h"
23 :
24 : #include "tree-diagnostic.h"
25 :
26 : #include "gimple-pretty-print.h"
27 : #include "gimple-iterator.h"
28 : #include "tree-cfg.h"
29 : #include "tree-dfa.h"
30 : #include "fold-const.h"
31 : #include "cgraph.h"
32 : #include "text-art/dump.h"
33 : #include "text-art/tree-widget.h"
34 :
35 : #include "analyzer/ops.h"
36 : #include "analyzer/call-details.h"
37 : #include "analyzer/exploded-graph.h"
38 : #include "analyzer/checker-path.h"
39 : #include "analyzer/impl-sm-context.h"
40 : #include "analyzer/constraint-manager.h"
41 : #include "analyzer/call-summary.h"
42 : #include "analyzer/call-info.h"
43 : #include "analyzer/analysis-plan.h"
44 : #include "analyzer/callsite-expr.h"
45 : #include "analyzer/state-transition.h"
46 :
47 : #if ENABLE_ANALYZER
48 :
49 : namespace ana {
50 :
51 : // class state_transition
52 :
53 : DEBUG_FUNCTION void
54 0 : state_transition::dump () const
55 : {
56 0 : tree_dump_pretty_printer pp (stderr);
57 0 : dump_to_pp (&pp);
58 0 : pp_newline (&pp);
59 0 : }
60 :
61 : std::unique_ptr<state_transition>
62 53 : state_transition::make (const region *src_reg,
63 : tree src_reg_expr,
64 : const region *dst_reg,
65 : tree dst_reg_expr)
66 : {
67 53 : gcc_assert (src_reg != dst_reg);
68 53 : gcc_assert (dst_reg);
69 :
70 53 : if (!src_reg)
71 0 : return std::make_unique<state_transition_origin> (dst_reg_expr);
72 :
73 53 : if (src_reg->get_parent_region () == dst_reg->get_parent_region ())
74 45 : if (tree src_decl = src_reg->maybe_get_decl ())
75 45 : if (tree dst_decl = dst_reg->maybe_get_decl ())
76 : {
77 45 : if (TREE_CODE (src_decl) == SSA_NAME
78 43 : && TREE_CODE (dst_decl) == SSA_NAME
79 25 : && SSA_NAME_VAR (src_decl)
80 63 : && SSA_NAME_VAR (src_decl) == SSA_NAME_VAR (dst_decl))
81 : {
82 : /* Avoid printing "copying value from 'y' to 'y'. */
83 14 : return nullptr;
84 : }
85 : }
86 :
87 39 : if (printable_expr_p (src_reg_expr))
88 : {
89 14 : if (printable_expr_p (dst_reg_expr))
90 6 : return std::make_unique<state_transition_copy> (src_reg_expr,
91 6 : dst_reg_expr);
92 : else
93 8 : return std::make_unique<state_transition_use> (src_reg_expr);
94 : }
95 : else
96 25 : return nullptr;
97 : }
98 :
99 : diagnostics::paths::event_id_t
100 204 : state_transition::get_src_event_id () const
101 : {
102 204 : if (!m_prev_state_transition)
103 90 : return diagnostics::paths::event_id_t ();
104 114 : return m_prev_state_transition->m_event_id;
105 : }
106 : // class state_transition_origin : public state_transition
107 :
108 : std::unique_ptr<state_transition>
109 0 : state_transition_origin::clone () const
110 : {
111 0 : return std::make_unique<state_transition_origin> (m_dst_reg_expr);
112 : }
113 :
114 : void
115 0 : state_transition_origin::dump_to_pp (pretty_printer *pp) const
116 : {
117 0 : pp_printf (pp, "state_transition_origin (dst: %qE)",
118 0 : m_dst_reg_expr);
119 0 : }
120 :
121 : // class state_transition_at_call : public state_transition
122 :
123 : std::unique_ptr<state_transition>
124 0 : state_transition_at_call::clone () const
125 : {
126 0 : return std::make_unique<state_transition_at_call> (m_expr);
127 : }
128 :
129 : void
130 0 : state_transition_at_call::dump_to_pp (pretty_printer *pp) const
131 : {
132 0 : callsite_expr_element e (m_expr);
133 0 : pp_printf (pp, "state_transition_at_call (callsite_expr: %e)", &e);
134 0 : }
135 :
136 : // class state_transition_at_return : public state_transition
137 :
138 : std::unique_ptr<state_transition>
139 0 : state_transition_at_return::clone () const
140 : {
141 0 : return std::make_unique<state_transition_at_return> ();
142 : }
143 :
144 : void
145 0 : state_transition_at_return::dump_to_pp (pretty_printer *pp) const
146 : {
147 0 : pp_printf (pp, "state_transition_at_return");
148 0 : }
149 :
150 : // class state_transition_copy : public state_transition
151 :
152 : std::unique_ptr<state_transition>
153 0 : state_transition_copy::clone () const
154 : {
155 0 : return std::make_unique<state_transition_copy> (m_src_reg_expr,
156 0 : m_dst_reg_expr);
157 : }
158 :
159 : void
160 0 : state_transition_copy::dump_to_pp (pretty_printer *pp) const
161 : {
162 0 : pp_printf (pp, "state_transition_copy (src: %qE, dst: %qE)",
163 0 : m_src_reg_expr,
164 0 : m_dst_reg_expr);
165 0 : }
166 :
167 : // class state_transition_use : public state_transition
168 :
169 : std::unique_ptr<state_transition>
170 0 : state_transition_use::clone () const
171 : {
172 0 : return std::make_unique<state_transition_use> (m_src_reg_expr);
173 : }
174 :
175 : void
176 0 : state_transition_use::dump_to_pp (pretty_printer *pp) const
177 : {
178 0 : pp_printf (pp, "state_transition_use (src: %qE)",
179 0 : m_src_reg_expr);
180 0 : }
181 :
182 : } // namespace ana
183 :
184 : #endif /* #if ENABLE_ANALYZER */
|