1 /* Classes for saving, deduplicating, and emitting analyzer diagnostics.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
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)
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.
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/>. */
21 #ifndef GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
22 #define GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
28 /* A to-be-emitted diagnostic stored within diagnostic_manager. */
30 class saved_diagnostic
33 saved_diagnostic (const state_machine
*sm
,
34 const pending_location
&ploc
,
35 tree var
, const svalue
*sval
,
36 state_machine::state_t state
,
37 std::unique_ptr
<pending_diagnostic
> d
,
40 bool operator== (const saved_diagnostic
&other
) const;
42 void add_note (std::unique_ptr
<pending_note
> pn
);
43 void add_event (std::unique_ptr
<checker_event
> event
);
45 json::object
*to_json () const;
47 void dump_dot_id (pretty_printer
*pp
) const;
48 void dump_as_dot_node (pretty_printer
*pp
) const;
50 const feasibility_problem
*get_feasibility_problem () const
52 return m_problem
.get ();
55 bool calc_best_epath (epath_finder
*pf
);
56 const exploded_path
*get_best_epath () const { return m_best_epath
.get (); }
57 unsigned get_epath_length () const;
59 void add_duplicate (saved_diagnostic
*other
);
60 unsigned get_num_dupes () const { return m_duplicates
.length (); }
62 unsigned get_index () const { return m_idx
; }
64 bool supercedes_p (const saved_diagnostic
&other
) const;
66 void add_any_saved_events (checker_path
&dst_path
);
68 void emit_any_notes () const;
71 const state_machine
*m_sm
;
72 const exploded_node
*m_enode
;
73 const supernode
*m_snode
;
75 std::unique_ptr
<stmt_finder
> m_stmt_finder
;
79 state_machine::state_t m_state
;
80 std::unique_ptr
<pending_diagnostic
> m_d
;
81 const exploded_edge
*m_trailing_eedge
;
84 DISABLE_COPY_AND_ASSIGN (saved_diagnostic
);
87 std::unique_ptr
<exploded_path
> m_best_epath
;
88 std::unique_ptr
<feasibility_problem
> m_problem
;
90 auto_vec
<const saved_diagnostic
*> m_duplicates
;
91 auto_delete_vec
<pending_note
> m_notes
;
93 /* Optionally: additional context-dependent events to be emitted
94 immediately before the warning_event, giving more details of what
95 operation was being simulated when a diagnostic was saved
96 e.g. "looking for null terminator in param 2 of 'foo'". */
97 auto_delete_vec
<checker_event
> m_saved_events
;
102 /* A bundle of information capturing where a pending_diagnostic should
105 struct pending_location
108 pending_location (exploded_node
*enode
,
109 const supernode
*snode
,
111 const stmt_finder
*finder
)
116 m_loc (UNKNOWN_LOCATION
)
118 gcc_assert (m_stmt
|| m_finder
);
121 /* ctor for cases where we have a location_t but there isn't any
122 gimple stmt associated with the diagnostic. */
124 pending_location (exploded_node
*enode
,
125 const supernode
*snode
,
135 exploded_node
*m_enode
;
136 const supernode
*m_snode
;
137 const gimple
*m_stmt
;
138 const stmt_finder
*m_finder
;
142 /* A class with responsibility for saving pending diagnostics, so that
143 they can be emitted after the exploded_graph is complete.
144 This lets us de-duplicate diagnostics, and find the shortest path
145 for each similar diagnostic, potentially using edges that might
146 not have been found when each diagnostic was first saved.
148 This also lets us compute shortest_paths once, rather than
151 class diagnostic_manager
: public log_user
154 diagnostic_manager (logger
*logger
, engine
*eng
, int verbosity
);
156 engine
*get_engine () const { return m_eng
; }
158 json::object
*to_json () const;
160 bool add_diagnostic (const state_machine
*sm
,
161 const pending_location
&ploc
,
164 state_machine::state_t state
,
165 std::unique_ptr
<pending_diagnostic
> d
);
167 bool add_diagnostic (const pending_location
&ploc
,
168 std::unique_ptr
<pending_diagnostic
> d
);
170 void add_note (std::unique_ptr
<pending_note
> pn
);
171 void add_event (std::unique_ptr
<checker_event
> event
);
173 void emit_saved_diagnostics (const exploded_graph
&eg
);
175 void emit_saved_diagnostic (const exploded_graph
&eg
,
176 saved_diagnostic
&sd
);
178 unsigned get_num_diagnostics () const
180 return m_saved_diagnostics
.length ();
182 saved_diagnostic
*get_saved_diagnostic (unsigned idx
)
184 return m_saved_diagnostics
[idx
];
186 const saved_diagnostic
*get_saved_diagnostic (unsigned idx
) const
188 return m_saved_diagnostics
[idx
];
192 void build_emission_path (const path_builder
&pb
,
193 const exploded_path
&epath
,
194 checker_path
*emission_path
) const;
196 void add_event_on_final_node (const path_builder
&pb
,
197 const exploded_node
*final_enode
,
198 checker_path
*emission_path
,
199 interesting_t
*interest
) const;
201 void add_events_for_eedge (const path_builder
&pb
,
202 const exploded_edge
&eedge
,
203 checker_path
*emission_path
,
204 interesting_t
*interest
) const;
206 bool significant_edge_p (const path_builder
&pb
,
207 const exploded_edge
&eedge
) const;
209 void add_events_for_superedge (const path_builder
&pb
,
210 const exploded_edge
&eedge
,
211 checker_path
*emission_path
) const;
213 void prune_path (checker_path
*path
,
214 const state_machine
*sm
,
216 state_machine::state_t state
) const;
218 void prune_for_sm_diagnostic (checker_path
*path
,
219 const state_machine
*sm
,
221 state_machine::state_t state
) const;
222 void prune_for_sm_diagnostic (checker_path
*path
,
223 const state_machine
*sm
,
225 state_machine::state_t state
) const;
226 void update_for_unsuitable_sm_exprs (tree
*expr
) const;
227 void prune_interproc_events (checker_path
*path
) const;
228 void prune_system_headers (checker_path
*path
) const;
229 void consolidate_conditions (checker_path
*path
) const;
230 void finish_pruning (checker_path
*path
) const;
233 auto_delete_vec
<saved_diagnostic
> m_saved_diagnostics
;
234 const int m_verbosity
;
235 int m_num_disabled_diagnostics
;
240 #endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */