Branch data Line data Source code
1 : : /* Subclass of diagnostic_path for analyzer diagnostics.
2 : : Copyright (C) 2019-2024 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 : :
26 : : namespace ana {
27 : :
28 : : /* Subclass of diagnostic_path for analyzer diagnostics. */
29 : :
30 : : class checker_path : public diagnostic_path
31 : : {
32 : : public:
33 : 4511 : checker_path (logger *logger)
34 : 4511 : : diagnostic_path (),
35 : 4511 : m_thread ("main"),
36 : 4511 : m_logger (logger)
37 : 4511 : {}
38 : :
39 : : /* Implementation of diagnostic_path vfuncs. */
40 : :
41 : 162615 : unsigned num_events () const final override
42 : : {
43 : 302243 : return m_events.length ();
44 : : }
45 : :
46 : 49099 : const diagnostic_event & get_event (int idx) const final override
47 : : {
48 : 49099 : return *m_events[idx];
49 : : }
50 : 0 : unsigned num_threads () const final override
51 : : {
52 : 0 : return 1;
53 : : }
54 : : const diagnostic_thread &
55 : 263 : get_thread (diagnostic_thread_id_t) const final override
56 : : {
57 : 263 : return m_thread;
58 : : }
59 : :
60 : 136200 : checker_event *get_checker_event (int idx)
61 : : {
62 : 136200 : return m_events[idx];
63 : : }
64 : :
65 : : void dump (pretty_printer *pp) const;
66 : : void debug () const;
67 : :
68 : 94 : logger *get_logger () const { return m_logger; }
69 : : void maybe_log (logger *logger, const char *desc) const;
70 : :
71 : : void add_event (std::unique_ptr<checker_event> event);
72 : :
73 : 46436 : void delete_event (int idx)
74 : : {
75 : 46436 : checker_event *event = m_events[idx];
76 : 46436 : m_events.ordered_remove (idx);
77 : 46436 : delete event;
78 : 46436 : }
79 : :
80 : 81 : void delete_events (unsigned start_idx, unsigned len)
81 : : {
82 : 261 : for (unsigned i = start_idx; i < start_idx + len; i++)
83 : 180 : delete m_events[i];
84 : 81 : m_events.block_remove (start_idx, len);
85 : 81 : }
86 : :
87 : 162 : void replace_event (unsigned idx, checker_event *new_event)
88 : : {
89 : 162 : delete m_events[idx];
90 : 162 : m_events[idx] = new_event;
91 : 162 : }
92 : :
93 : : void add_region_creation_events (pending_diagnostic *pd,
94 : : const region *reg,
95 : : const region_model *model,
96 : : const event_loc_info &loc_info,
97 : : bool debug);
98 : :
99 : : /* After all event-pruning, a hook for notifying each event what
100 : : its ID will be. The events are notified in order, allowing
101 : : for later events to refer to the IDs of earlier events in
102 : : their descriptions. */
103 : 4511 : void prepare_for_emission (pending_diagnostic *pd)
104 : : {
105 : 4511 : checker_event *e;
106 : 4511 : int i;
107 : 23701 : FOR_EACH_VEC_ELT (m_events, i, e)
108 : 19190 : e->prepare_for_emission (this, pd, diagnostic_event_id_t (i));
109 : 4511 : }
110 : :
111 : : void fixup_locations (pending_diagnostic *pd);
112 : :
113 : 23 : void record_setjmp_event (const exploded_node *enode,
114 : : diagnostic_event_id_t setjmp_emission_id)
115 : : {
116 : 23 : m_setjmp_event_ids.put (enode, setjmp_emission_id);
117 : : }
118 : :
119 : 17 : bool get_setjmp_event (const exploded_node *enode,
120 : : diagnostic_event_id_t *out_emission_id)
121 : : {
122 : 17 : if (diagnostic_event_id_t *emission_id = m_setjmp_event_ids.get (enode))
123 : : {
124 : 17 : *out_emission_id = *emission_id;
125 : 17 : return true;
126 : : }
127 : : return false;
128 : : }
129 : :
130 : : bool cfg_edge_pair_at_p (unsigned idx) const;
131 : :
132 : : void inject_any_inlined_call_events (logger *logger);
133 : :
134 : : private:
135 : : DISABLE_COPY_AND_ASSIGN(checker_path);
136 : :
137 : : simple_diagnostic_thread m_thread;
138 : :
139 : : /* The events that have occurred along this path. */
140 : : auto_delete_vec<checker_event> m_events;
141 : :
142 : : /* During prepare_for_emission (and after), the setjmp_event for each
143 : : exploded_node *, so that rewind events can refer to them in their
144 : : descriptions. */
145 : : hash_map <const exploded_node *, diagnostic_event_id_t> m_setjmp_event_ids;
146 : :
147 : : logger *m_logger;
148 : : };
149 : :
150 : : } // namespace ana
151 : :
152 : : #endif /* GCC_ANALYZER_CHECKER_PATH_H */
|