]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/diagnostic-manager.h
analyzer: introduce pending_location
[thirdparty/gcc.git] / gcc / analyzer / diagnostic-manager.h
CommitLineData
757bf1df 1/* Classes for saving, deduplicating, and emitting analyzer diagnostics.
83ffe9cd 2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
757bf1df
DM
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
22#define GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
23
75038aa6
DM
24namespace ana {
25
a505fad4
DM
26class epath_finder;
27
757bf1df
DM
28/* A to-be-emitted diagnostic stored within diagnostic_manager. */
29
30class saved_diagnostic
31{
32public:
33 saved_diagnostic (const state_machine *sm,
759a1a52 34 const pending_location &ploc,
808f4dfe
DM
35 tree var, const svalue *sval,
36 state_machine::state_t state,
6341f14e 37 std::unique_ptr<pending_diagnostic> d,
3857edb5 38 unsigned idx);
757bf1df 39
14f9d7b9 40 bool operator== (const saved_diagnostic &other) const;
757bf1df 41
6341f14e 42 void add_note (std::unique_ptr<pending_note> pn);
2503dd59 43 void add_event (std::unique_ptr<checker_event> event);
c65d3c7f 44
809192e7
DM
45 json::object *to_json () const;
46
c540077a
DM
47 void dump_dot_id (pretty_printer *pp) const;
48 void dump_as_dot_node (pretty_printer *pp) const;
49
42c63313
DM
50 const feasibility_problem *get_feasibility_problem () const
51 {
e031c5a1 52 return m_problem.get ();
42c63313
DM
53 }
54
a505fad4 55 bool calc_best_epath (epath_finder *pf);
e031c5a1 56 const exploded_path *get_best_epath () const { return m_best_epath.get (); }
a505fad4 57 unsigned get_epath_length () const;
42c63313 58
a505fad4
DM
59 void add_duplicate (saved_diagnostic *other);
60 unsigned get_num_dupes () const { return m_duplicates.length (); }
42c63313 61
3857edb5
DM
62 unsigned get_index () const { return m_idx; }
63
33255ad3
DM
64 bool supercedes_p (const saved_diagnostic &other) const;
65
2503dd59
DM
66 void add_any_saved_events (checker_path &dst_path);
67
c65d3c7f
DM
68 void emit_any_notes () const;
69
757bf1df
DM
70 //private:
71 const state_machine *m_sm;
72 const exploded_node *m_enode;
73 const supernode *m_snode;
74 const gimple *m_stmt;
2a9b395b 75 std::unique_ptr<stmt_finder> m_stmt_finder;
757bf1df 76 tree m_var;
808f4dfe 77 const svalue *m_sval;
757bf1df 78 state_machine::state_t m_state;
6341f14e 79 std::unique_ptr<pending_diagnostic> m_d;
a505fad4 80 const exploded_edge *m_trailing_eedge;
757bf1df
DM
81
82private:
83 DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
42c63313 84
3857edb5 85 unsigned m_idx;
e031c5a1
DM
86 std::unique_ptr<exploded_path> m_best_epath;
87 std::unique_ptr<feasibility_problem> m_problem;
a505fad4
DM
88
89 auto_vec<const saved_diagnostic *> m_duplicates;
c65d3c7f 90 auto_delete_vec <pending_note> m_notes;
2503dd59
DM
91
92 /* Optionally: additional context-dependent events to be emitted
93 immediately before the warning_event, giving more details of what
94 operation was being simulated when a diagnostic was saved
95 e.g. "looking for null terminator in param 2 of 'foo'". */
96 auto_delete_vec <checker_event> m_saved_events;
757bf1df
DM
97};
98
004f2c07
DM
99class path_builder;
100
759a1a52
DM
101/* A bundle of information capturing where a pending_diagnostic should
102 be emitted. */
103
104struct pending_location
105{
106public:
107 pending_location (exploded_node *enode,
108 const supernode *snode,
109 const gimple *stmt,
110 const stmt_finder *finder)
111 : m_enode (enode),
112 m_snode (snode),
113 m_stmt (stmt),
114 m_finder (finder)
115 {
116 gcc_assert (m_stmt || m_finder);
117 }
118
119 exploded_node *m_enode;
120 const supernode *m_snode;
121 const gimple *m_stmt;
122 const stmt_finder *m_finder;
123};
124
757bf1df
DM
125/* A class with responsibility for saving pending diagnostics, so that
126 they can be emitted after the exploded_graph is complete.
127 This lets us de-duplicate diagnostics, and find the shortest path
128 for each similar diagnostic, potentially using edges that might
129 not have been found when each diagnostic was first saved.
130
131 This also lets us compute shortest_paths once, rather than
132 per-diagnostic. */
133
134class diagnostic_manager : public log_user
135{
136public:
808f4dfe
DM
137 diagnostic_manager (logger *logger, engine *eng, int verbosity);
138
139 engine *get_engine () const { return m_eng; }
757bf1df 140
809192e7
DM
141 json::object *to_json () const;
142
160b095f 143 bool add_diagnostic (const state_machine *sm,
759a1a52 144 const pending_location &ploc,
808f4dfe
DM
145 tree var,
146 const svalue *sval,
147 state_machine::state_t state,
6341f14e 148 std::unique_ptr<pending_diagnostic> d);
757bf1df 149
759a1a52 150 bool add_diagnostic (const pending_location &ploc,
6341f14e 151 std::unique_ptr<pending_diagnostic> d);
757bf1df 152
6341f14e 153 void add_note (std::unique_ptr<pending_note> pn);
2503dd59 154 void add_event (std::unique_ptr<checker_event> event);
c65d3c7f 155
757bf1df
DM
156 void emit_saved_diagnostics (const exploded_graph &eg);
157
158 void emit_saved_diagnostic (const exploded_graph &eg,
2503dd59 159 saved_diagnostic &sd);
757bf1df
DM
160
161 unsigned get_num_diagnostics () const
162 {
163 return m_saved_diagnostics.length ();
164 }
165 saved_diagnostic *get_saved_diagnostic (unsigned idx)
166 {
167 return m_saved_diagnostics[idx];
168 }
67098787
DM
169 const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
170 {
171 return m_saved_diagnostics[idx];
172 }
757bf1df
DM
173
174private:
004f2c07 175 void build_emission_path (const path_builder &pb,
757bf1df
DM
176 const exploded_path &epath,
177 checker_path *emission_path) const;
178
f5758fe5
DM
179 void add_event_on_final_node (const path_builder &pb,
180 const exploded_node *final_enode,
e6c3bb37
TL
181 checker_path *emission_path,
182 interesting_t *interest) const;
183
004f2c07
DM
184 void add_events_for_eedge (const path_builder &pb,
185 const exploded_edge &eedge,
00e7d024
DM
186 checker_path *emission_path,
187 interesting_t *interest) const;
757bf1df 188
004f2c07
DM
189 bool significant_edge_p (const path_builder &pb,
190 const exploded_edge &eedge) const;
191
192 void add_events_for_superedge (const path_builder &pb,
193 const exploded_edge &eedge,
757bf1df
DM
194 checker_path *emission_path) const;
195
196 void prune_path (checker_path *path,
197 const state_machine *sm,
808f4dfe
DM
198 const svalue *sval,
199 state_machine::state_t state) const;
757bf1df
DM
200
201 void prune_for_sm_diagnostic (checker_path *path,
202 const state_machine *sm,
203 tree var,
204 state_machine::state_t state) const;
808f4dfe
DM
205 void prune_for_sm_diagnostic (checker_path *path,
206 const state_machine *sm,
207 const svalue *sval,
208 state_machine::state_t state) const;
3d66e153 209 void update_for_unsuitable_sm_exprs (tree *expr) const;
757bf1df 210 void prune_interproc_events (checker_path *path) const;
ce8cdf5b 211 void prune_system_headers (checker_path *path) const;
eb06fdd4 212 void consolidate_conditions (checker_path *path) const;
757bf1df
DM
213 void finish_pruning (checker_path *path) const;
214
808f4dfe 215 engine *m_eng;
757bf1df
DM
216 auto_delete_vec<saved_diagnostic> m_saved_diagnostics;
217 const int m_verbosity;
7fd6e36e 218 int m_num_disabled_diagnostics;
757bf1df
DM
219};
220
75038aa6
DM
221} // namespace ana
222
757bf1df 223#endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */