1 /* Classes for saving, deduplicating, and emitting analyzer diagnostics.
2 Copyright (C) 2019-2024 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;
70 void maybe_add_sarif_properties (sarif_object
&result_obj
) const;
73 const state_machine
*m_sm
;
74 const exploded_node
*m_enode
;
75 const supernode
*m_snode
;
77 std::unique_ptr
<stmt_finder
> m_stmt_finder
;
81 state_machine::state_t m_state
;
82 std::unique_ptr
<pending_diagnostic
> m_d
;
83 const exploded_edge
*m_trailing_eedge
;
86 DISABLE_COPY_AND_ASSIGN (saved_diagnostic
);
89 std::unique_ptr
<exploded_path
> m_best_epath
;
90 std::unique_ptr
<feasibility_problem
> m_problem
;
92 auto_vec
<const saved_diagnostic
*> m_duplicates
;
93 auto_delete_vec
<pending_note
> m_notes
;
95 /* Optionally: additional context-dependent events to be emitted
96 immediately before the warning_event, giving more details of what
97 operation was being simulated when a diagnostic was saved
98 e.g. "looking for null terminator in param 2 of 'foo'". */
99 auto_delete_vec
<checker_event
> m_saved_events
;
104 /* A bundle of information capturing where a pending_diagnostic should
107 struct pending_location
110 pending_location (exploded_node
*enode
,
111 const supernode
*snode
,
113 const stmt_finder
*finder
)
118 m_loc (UNKNOWN_LOCATION
)
120 gcc_assert (m_stmt
|| m_finder
);
123 /* ctor for cases where we have a location_t but there isn't any
124 gimple stmt associated with the diagnostic. */
126 pending_location (exploded_node
*enode
,
127 const supernode
*snode
,
137 exploded_node
*m_enode
;
138 const supernode
*m_snode
;
139 const gimple
*m_stmt
;
140 const stmt_finder
*m_finder
;
144 /* A class with responsibility for saving pending diagnostics, so that
145 they can be emitted after the exploded_graph is complete.
146 This lets us de-duplicate diagnostics, and find the shortest path
147 for each similar diagnostic, potentially using edges that might
148 not have been found when each diagnostic was first saved.
150 This also lets us compute shortest_paths once, rather than
153 class diagnostic_manager
: public log_user
156 diagnostic_manager (logger
*logger
, engine
*eng
, int verbosity
);
158 engine
*get_engine () const { return m_eng
; }
160 json::object
*to_json () const;
162 bool add_diagnostic (const state_machine
*sm
,
163 const pending_location
&ploc
,
166 state_machine::state_t state
,
167 std::unique_ptr
<pending_diagnostic
> d
);
169 bool add_diagnostic (const pending_location
&ploc
,
170 std::unique_ptr
<pending_diagnostic
> d
);
172 void add_note (std::unique_ptr
<pending_note
> pn
);
173 void add_event (std::unique_ptr
<checker_event
> event
);
175 void emit_saved_diagnostics (const exploded_graph
&eg
);
177 void emit_saved_diagnostic (const exploded_graph
&eg
,
178 saved_diagnostic
&sd
);
180 unsigned get_num_diagnostics () const
182 return m_saved_diagnostics
.length ();
184 saved_diagnostic
*get_saved_diagnostic (unsigned idx
)
186 return m_saved_diagnostics
[idx
];
188 const saved_diagnostic
*get_saved_diagnostic (unsigned idx
) const
190 return m_saved_diagnostics
[idx
];
194 void build_emission_path (const path_builder
&pb
,
195 const exploded_path
&epath
,
196 checker_path
*emission_path
) const;
198 void add_event_on_final_node (const path_builder
&pb
,
199 const exploded_node
*final_enode
,
200 checker_path
*emission_path
,
201 interesting_t
*interest
) const;
203 void add_events_for_eedge (const path_builder
&pb
,
204 const exploded_edge
&eedge
,
205 checker_path
*emission_path
,
206 interesting_t
*interest
) const;
208 bool significant_edge_p (const path_builder
&pb
,
209 const exploded_edge
&eedge
) const;
211 void add_events_for_superedge (const path_builder
&pb
,
212 const exploded_edge
&eedge
,
213 checker_path
*emission_path
) const;
215 void prune_path (checker_path
*path
,
216 const state_machine
*sm
,
218 state_machine::state_t state
) const;
220 void prune_for_sm_diagnostic (checker_path
*path
,
221 const state_machine
*sm
,
223 state_machine::state_t state
) const;
224 void prune_for_sm_diagnostic (checker_path
*path
,
225 const state_machine
*sm
,
227 state_machine::state_t state
) const;
228 void update_for_unsuitable_sm_exprs (tree
*expr
) const;
229 void prune_interproc_events (checker_path
*path
) const;
230 void prune_system_headers (checker_path
*path
) const;
231 void consolidate_conditions (checker_path
*path
) const;
232 void finish_pruning (checker_path
*path
) const;
235 auto_delete_vec
<saved_diagnostic
> m_saved_diagnostics
;
236 const int m_verbosity
;
237 int m_num_disabled_diagnostics
;
242 #endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */