Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / analyzer / diagnostic-manager.h
blob27ab9ed068eb43a644a247ab3e22ac4ae4d2e947
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)
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 //private:
71 const state_machine *m_sm;
72 const exploded_node *m_enode;
73 const supernode *m_snode;
74 const gimple *m_stmt;
75 std::unique_ptr<stmt_finder> m_stmt_finder;
76 location_t m_loc;
77 tree m_var;
78 const svalue *m_sval;
79 state_machine::state_t m_state;
80 std::unique_ptr<pending_diagnostic> m_d;
81 const exploded_edge *m_trailing_eedge;
83 private:
84 DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
86 unsigned m_idx;
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;
100 class path_builder;
102 /* A bundle of information capturing where a pending_diagnostic should
103 be emitted. */
105 struct pending_location
107 public:
108 pending_location (exploded_node *enode,
109 const supernode *snode,
110 const gimple *stmt,
111 const stmt_finder *finder)
112 : m_enode (enode),
113 m_snode (snode),
114 m_stmt (stmt),
115 m_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,
126 location_t loc)
127 : m_enode (enode),
128 m_snode (snode),
129 m_stmt (nullptr),
130 m_finder (nullptr),
131 m_loc (loc)
135 exploded_node *m_enode;
136 const supernode *m_snode;
137 const gimple *m_stmt;
138 const stmt_finder *m_finder;
139 location_t m_loc;
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
149 per-diagnostic. */
151 class diagnostic_manager : public log_user
153 public:
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,
162 tree var,
163 const svalue *sval,
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];
191 private:
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,
215 const svalue *sval,
216 state_machine::state_t state) const;
218 void prune_for_sm_diagnostic (checker_path *path,
219 const state_machine *sm,
220 tree var,
221 state_machine::state_t state) const;
222 void prune_for_sm_diagnostic (checker_path *path,
223 const state_machine *sm,
224 const svalue *sval,
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;
232 engine *m_eng;
233 auto_delete_vec<saved_diagnostic> m_saved_diagnostics;
234 const int m_verbosity;
235 int m_num_disabled_diagnostics;
238 } // namespace ana
240 #endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */