Branch data Line data Source code
1 : : /* Subclass of diagnostics::paths::path for analyzer diagnostics.
2 : : Copyright (C) 2019-2025 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_ANALYZER_CHECKER_PATH_H
22 : : #define GCC_ANALYZER_CHECKER_PATH_H
23 : :
24 : : #include "analyzer/checker-event.h"
25 : : #include "simple-diagnostic-path.h"
26 : :
27 : : namespace ana {
28 : :
29 : : /* Subclass of diagnostic path for analyzer diagnostics. */
30 : :
31 : : class checker_path : public diagnostics::paths::path
32 : : {
33 : : public:
34 : 3980 : checker_path (const diagnostics::logical_locations::manager &logical_loc_mgr,
35 : : const extrinsic_state &ext_state,
36 : : logger *logger)
37 : 3980 : : diagnostics::paths::path (logical_loc_mgr),
38 : 3980 : m_ext_state (ext_state),
39 : 3980 : m_thread ("main"),
40 : 3980 : m_logger (logger)
41 : 3980 : {}
42 : :
43 : : /* Implementation of diagnostics::paths::path vfuncs. */
44 : :
45 : 162104 : unsigned num_events () const final override
46 : : {
47 : 303784 : return m_events.length ();
48 : : }
49 : :
50 : : const diagnostics::paths::event &
51 : 37195 : get_event (int idx) const final override
52 : : {
53 : 37195 : return *m_events[idx];
54 : : }
55 : 0 : unsigned num_threads () const final override
56 : : {
57 : 0 : return 1;
58 : : }
59 : : const diagnostics::paths::thread &
60 : 281 : get_thread (diagnostics::paths::thread_id_t) const final override
61 : : {
62 : 281 : return m_thread;
63 : : }
64 : :
65 : 28 : const extrinsic_state &get_ext_state () const { return m_ext_state; }
66 : :
67 : 6 : checker_event *get_checker_event (int idx)
68 : : {
69 : 135191 : return m_events[idx];
70 : : }
71 : :
72 : : bool
73 : : same_function_p (int event_idx_a,
74 : : int event_idx_b) const final override;
75 : :
76 : : void dump (pretty_printer *pp) const;
77 : : void debug () const;
78 : :
79 : 79 : logger *get_logger () const { return m_logger; }
80 : : void maybe_log (logger *logger, const char *desc) const;
81 : :
82 : : void add_event (std::unique_ptr<checker_event> event);
83 : :
84 : 42260 : void delete_event (int idx)
85 : : {
86 : 42260 : checker_event *event = m_events[idx];
87 : 42260 : m_events.ordered_remove (idx);
88 : 42260 : delete event;
89 : 42260 : }
90 : :
91 : 97 : void delete_events (unsigned start_idx, unsigned len)
92 : : {
93 : 295 : for (unsigned i = start_idx; i < start_idx + len; i++)
94 : 198 : delete m_events[i];
95 : 97 : m_events.block_remove (start_idx, len);
96 : 97 : }
97 : :
98 : 182 : void replace_event (unsigned idx, checker_event *new_event)
99 : : {
100 : 182 : delete m_events[idx];
101 : 182 : m_events[idx] = new_event;
102 : 182 : }
103 : :
104 : : void add_region_creation_events (pending_diagnostic *pd,
105 : : const region *reg,
106 : : const region_model *model,
107 : : const event_loc_info &loc_info,
108 : : bool debug);
109 : :
110 : : /* After all event-pruning, a hook for notifying each event what
111 : : its ID will be. The events are notified in order, allowing
112 : : for later events to refer to the IDs of earlier events in
113 : : their descriptions. */
114 : 3980 : void prepare_for_emission (pending_diagnostic *pd)
115 : : {
116 : 3980 : checker_event *e;
117 : 3980 : int i;
118 : 21126 : FOR_EACH_VEC_ELT (m_events, i, e)
119 : 17146 : e->prepare_for_emission (this, pd, diagnostics::paths::event_id_t (i));
120 : 3980 : }
121 : :
122 : : void fixup_locations (pending_diagnostic *pd);
123 : :
124 : 20 : void record_setjmp_event (const exploded_node *enode,
125 : : diagnostics::paths::event_id_t setjmp_emission_id)
126 : : {
127 : 20 : m_setjmp_event_ids.put (enode, setjmp_emission_id);
128 : : }
129 : :
130 : 15 : bool get_setjmp_event (const exploded_node *enode,
131 : : diagnostics::paths::event_id_t *out_emission_id)
132 : : {
133 : 30 : if (diagnostics::paths::event_id_t *emission_id
134 : 15 : = m_setjmp_event_ids.get (enode))
135 : : {
136 : 15 : *out_emission_id = *emission_id;
137 : 15 : return true;
138 : : }
139 : : return false;
140 : : }
141 : :
142 : : bool cfg_edge_pair_at_p (unsigned idx) const;
143 : :
144 : : void inject_any_inlined_call_events (logger *logger);
145 : :
146 : : private:
147 : : DISABLE_COPY_AND_ASSIGN(checker_path);
148 : :
149 : : const extrinsic_state &m_ext_state;
150 : :
151 : : simple_diagnostic_thread m_thread;
152 : :
153 : : /* The events that have occurred along this path. */
154 : : auto_delete_vec<checker_event> m_events;
155 : :
156 : : /* During prepare_for_emission (and after), the setjmp_event for each
157 : : exploded_node *, so that rewind events can refer to them in their
158 : : descriptions. */
159 : : hash_map <const exploded_node *, diagnostics::paths::event_id_t> m_setjmp_event_ids;
160 : :
161 : : logger *m_logger;
162 : : };
163 : :
164 : : } // namespace ana
165 : :
166 : : #endif /* GCC_ANALYZER_CHECKER_PATH_H */
|