libstdc++: Prefer posix_memalign for aligned-new [PR113258]
[official-gcc.git] / gcc / analyzer / diagnostic-manager.h
blob8d55344693e0abf0dea8070008738973e112a4cd
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)
10 any later version.
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
24 namespace ana {
26 class epath_finder;
28 /* A to-be-emitted diagnostic stored within diagnostic_manager. */
30 class saved_diagnostic
32 public:
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,
38 unsigned idx);
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;
72 //private:
73 const state_machine *m_sm;
74 const exploded_node *m_enode;
75 const supernode *m_snode;
76 const gimple *m_stmt;
77 std::unique_ptr<stmt_finder> m_stmt_finder;
78 location_t m_loc;
79 tree m_var;
80 const svalue *m_sval;
81 state_machine::state_t m_state;
82 std::unique_ptr<pending_diagnostic> m_d;
83 const exploded_edge *m_trailing_eedge;
85 private:
86 DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
88 unsigned m_idx;
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;
102 class path_builder;
104 /* A bundle of information capturing where a pending_diagnostic should
105 be emitted. */
107 struct pending_location
109 public:
110 pending_location (exploded_node *enode,
111 const supernode *snode,
112 const gimple *stmt,
113 const stmt_finder *finder)
114 : m_enode (enode),
115 m_snode (snode),
116 m_stmt (stmt),
117 m_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,
128 location_t loc)
129 : m_enode (enode),
130 m_snode (snode),
131 m_stmt (nullptr),
132 m_finder (nullptr),
133 m_loc (loc)
137 exploded_node *m_enode;
138 const supernode *m_snode;
139 const gimple *m_stmt;
140 const stmt_finder *m_finder;
141 location_t m_loc;
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
151 per-diagnostic. */
153 class diagnostic_manager : public log_user
155 public:
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,
164 tree var,
165 const svalue *sval,
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];
193 private:
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,
217 const svalue *sval,
218 state_machine::state_t state) const;
220 void prune_for_sm_diagnostic (checker_path *path,
221 const state_machine *sm,
222 tree var,
223 state_machine::state_t state) const;
224 void prune_for_sm_diagnostic (checker_path *path,
225 const state_machine *sm,
226 const svalue *sval,
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;
234 engine *m_eng;
235 auto_delete_vec<saved_diagnostic> m_saved_diagnostics;
236 const int m_verbosity;
237 int m_num_disabled_diagnostics;
240 } // namespace ana
242 #endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */