Line data Source code
1 : /* Subclass of diagnostics::paths::path for analyzer diagnostics.
2 : Copyright (C) 2019-2026 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 3991 : checker_path (const diagnostics::logical_locations::manager &logical_loc_mgr,
35 : const extrinsic_state &ext_state,
36 : logger *logger)
37 3991 : : diagnostics::paths::path (logical_loc_mgr),
38 3991 : m_ext_state (ext_state),
39 3991 : m_thread ("main"),
40 3991 : m_logger (logger)
41 3991 : {}
42 :
43 : /* Implementation of diagnostics::paths::path vfuncs. */
44 :
45 135038 : unsigned num_events () const final override
46 : {
47 249142 : return m_events.length ();
48 : }
49 :
50 : const diagnostics::paths::event &
51 36196 : get_event (int idx) const final override
52 : {
53 36196 : 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 355 : get_thread (diagnostics::paths::thread_id_t) const final override
61 : {
62 355 : return m_thread;
63 : }
64 :
65 13519 : const extrinsic_state &get_ext_state () const { return m_ext_state; }
66 :
67 6 : checker_event *get_checker_event (int idx)
68 : {
69 99457 : 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 91 : 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 19393 : void delete_event (int idx)
85 : {
86 19393 : checker_event *event = m_events[idx];
87 19393 : m_events.ordered_remove (idx);
88 19393 : delete event;
89 19393 : }
90 :
91 114 : void delete_events (unsigned start_idx, unsigned len)
92 : {
93 352 : for (unsigned i = start_idx; i < start_idx + len; i++)
94 238 : delete m_events[i];
95 114 : m_events.block_remove (start_idx, len);
96 114 : }
97 :
98 216 : void replace_event (unsigned idx, checker_event *new_event)
99 : {
100 216 : delete m_events[idx];
101 216 : m_events[idx] = new_event;
102 216 : }
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 3991 : void prepare_for_emission (pending_diagnostic *pd)
115 : {
116 3991 : checker_event *e;
117 3991 : int i;
118 20698 : FOR_EACH_VEC_ELT (m_events, i, e)
119 16707 : e->prepare_for_emission (this, pd, diagnostics::paths::event_id_t (i));
120 3991 : }
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 */
|