GCC Middle and Back End API Reference
paths.h
Go to the documentation of this file.
1/* Paths through the code associated with a diagnostic.
2 Copyright (C) 2019-2025 Free Software Foundation, Inc.
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 under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for 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_DIAGNOSTICS_PATHS_H
22#define GCC_DIAGNOSTICS_PATHS_H
23
24#include "diagnostic.h" /* for ATTRIBUTE_GCC_DIAG. */
27
28namespace diagnostics {
29 namespace digraphs {
30 class digraph;
31 } // namespace digraphs
32 namespace logical_locations {
33 class manager;
34 } // logical_locations
35 class sarif_builder;
36 class sarif_object;
37} //namespace diagnostics
38
39namespace diagnostics {
40namespace paths {
41
42/* A diagnostics::paths::path is an optional additional piece of metadata associated
43 with a diagnostic (via its rich_location).
44
45 It describes a sequence of events predicted by the compiler that
46 lead to the problem occurring, with their locations in the user's source,
47 and text descriptions.
48
49 For example, the following error has a 3-event path:
50
51 test.c: In function 'demo':
52 test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which
53 requires a non-NULL parameter
54 29 | PyList_Append(list, item);
55 | ^~~~~~~~~~~~~~~~~~~~~~~~~
56 'demo': events 1-3
57 25 | list = PyList_New(0);
58 | ^~~~~~~~~~~~~
59 | |
60 | (1) when 'PyList_New' fails, returning NULL
61 26 |
62 27 | for (i = 0; i < count; i++) {
63 | ~~~
64 | |
65 | (2) when 'i < count'
66 28 | item = PyLong_FromLong(random());
67 29 | PyList_Append(list, item);
68 | ~~~~~~~~~~~~~~~~~~~~~~~~~
69 | |
70 | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
71
72 The diagnostic-printing code has consolidated the path into a single
73 run of events, since all the events are near each other and within the same
74 function; more complicated examples (such as interprocedural paths)
75 might be printed as multiple runs of events. */
76
77/* Abstract base classes, describing events within a path, and the paths
78 themselves. */
79
80/* One event within a path. */
81
82class event
83{
84 public:
85 /* Enums for giving a sense of what this event means.
86 Roughly corresponds to SARIF v2.1.0 section 3.38.8. */
87 enum class verb
88 {
90
98
100
101 // Special control flow operations:
104 unwind_, // unwinding stack frame(s) during exception-handling
107 };
108 enum class noun
109 {
111
113 sensitive, // this one isn't in SARIF v2.1.0; filed as https://github.com/oasis-tcs/sarif-spec/issues/530
118 };
119 enum class property
120 {
122
125 };
126 /* A bundle of such enums, allowing for descriptions of the meaning of
127 an event, such as
128 - "acquire memory": meaning (verb::acquire, noun::memory)
129 - "take true branch"": meaning (verb::branch, property::true)
130 - "return from function": meaning (verb::return, noun::function)
131 etc, as per SARIF's threadFlowLocation "kinds" property
132 (SARIF v2.1.0 section 3.38.8). */
133 struct meaning
134 {
136 : m_verb (verb::unknown),
139 {
140 }
145 meaning (enum verb verb, enum noun noun)
147 {
148 }
153
154 void dump_to_pp (pretty_printer *pp) const;
155
156 static const char *maybe_get_verb_str (enum verb);
157 static const char *maybe_get_noun_str (enum noun);
158 static const char *maybe_get_property_str (enum property);
159
162 enum property m_property;
163 };
164
165 virtual ~event () {}
166
167 virtual location_t get_location () const = 0;
168
169 /* Stack depth, so that consumers can visualize the interprocedural
170 calls, returns, and frame nesting. */
171 virtual int get_stack_depth () const = 0;
172
173 /* Print a localized (and possibly colorized) description of this event. */
174 virtual void print_desc (pretty_printer &pp) const = 0;
175
176 /* Get a logical location for this event, or null if there is none. */
178
179 virtual meaning get_meaning () const = 0;
180
181 /* True iff we should draw a line connecting this event to the
182 next event (e.g. to highlight control flow). */
183 virtual bool connect_to_next_event_p () const = 0;
184
185 virtual thread_id_t get_thread_id () const = 0;
186
187 /* Hook for SARIF output to allow for adding diagnostic-specific
188 properties to the threadFlowLocation object's property bag. */
189 virtual void
191 sarif_object &/*thread_flow_loc_obj*/) const
192 {
193 }
194
195 /* Hook for capturing state at this event, potentially for visualizing
196 in HTML output, or for adding to SARIF. */
197 virtual std::unique_ptr<digraphs::digraph>
199
200 label_text get_desc (pretty_printer &ref_pp) const;
201};
202
203/* Abstract base class representing a thread of execution within
204 a diagnostics::paths::path.
205 Each event is associated with one thread.
206 Typically there is just one thread per diagnostics::paths::path. */
207
209{
210public:
211 virtual ~thread () {}
212 virtual label_text get_name (bool can_colorize) const = 0;
213};
214
215/* Abstract base class for getting at a sequence of events. */
216
217class path
218{
219 public:
220 virtual ~path () {}
221 virtual unsigned num_events () const = 0;
222 virtual const event & get_event (int idx) const = 0;
223 virtual unsigned num_threads () const = 0;
224 virtual const thread &
226
227 /* Return true iff the two events are both within the same function,
228 or both outside of any function. */
229 virtual bool
230 same_function_p (int event_idx_a,
231 int event_idx_b) const = 0;
232
233 bool interprocedural_p () const;
234 bool multithreaded_p () const;
235
240
241protected:
242 path (const logical_locations::manager &logical_loc_mgr)
243 : m_logical_loc_mgr (logical_loc_mgr)
244 {
245 }
246
247private:
248 bool get_first_event_in_a_function (unsigned *out_idx) const;
249
251};
252
253} // namespace paths
254} // namespace diagnostics
255
256/* Concrete subclasses of the above can be found in
257 simple-diagnostic-path.h. */
258
259extern void debug (diagnostics::paths::path *path);
260
261#endif /* ! GCC_DIAGNOSTICS_PATHS_H */
Definition diagnostics/digraphs.h:123
Definition logical-locations.h:101
Definition logical-locations.h:147
Definition paths.h:83
virtual void print_desc(pretty_printer &pp) const =0
virtual location_t get_location() const =0
virtual bool connect_to_next_event_p() const =0
virtual logical_locations::key get_logical_location() const =0
virtual void maybe_add_sarif_properties(sarif_builder &, sarif_object &) const
Definition paths.h:190
virtual int get_stack_depth() const =0
verb
Definition paths.h:88
@ throw_
Definition paths.h:102
@ release
Definition paths.h:92
@ setjmp_
Definition paths.h:105
@ call
Definition paths.h:95
@ longjmp_
Definition paths.h:106
@ catch_
Definition paths.h:103
@ acquire
Definition paths.h:91
@ branch
Definition paths.h:97
@ unknown
Definition paths.h:89
@ danger
Definition paths.h:99
@ return_
Definition paths.h:96
@ unwind_
Definition paths.h:104
@ enter
Definition paths.h:93
@ exit
Definition paths.h:94
virtual std::unique_ptr< digraphs::digraph > maybe_make_diagnostic_state_graph(bool debug) const
Definition paths.cc:180
virtual thread_id_t get_thread_id() const =0
property
Definition paths.h:120
@ true_
Definition paths.h:123
@ false_
Definition paths.h:124
noun
Definition paths.h:109
@ taint
Definition paths.h:112
@ sensitive
Definition paths.h:113
@ resource
Definition paths.h:117
@ memory
Definition paths.h:116
@ lock
Definition paths.h:115
virtual ~event()
Definition paths.h:165
label_text get_desc(pretty_printer &ref_pp) const
Definition paths.cc:169
virtual meaning get_meaning() const =0
Definition paths.h:218
bool interprocedural_p() const
Definition paths.cc:215
const logical_locations::manager & m_logical_loc_mgr
Definition paths.h:250
virtual unsigned num_threads() const =0
virtual const event & get_event(int idx) const =0
virtual unsigned num_events() const =0
bool get_first_event_in_a_function(unsigned *out_idx) const
Definition paths.cc:195
path(const logical_locations::manager &logical_loc_mgr)
Definition paths.h:242
virtual ~path()
Definition paths.h:220
virtual const thread & get_thread(thread_id_t) const =0
virtual bool same_function_p(int event_idx_a, int event_idx_b) const =0
bool multithreaded_p() const
const logical_locations::manager & get_logical_location_manager() const
Definition paths.h:236
Definition paths.h:209
virtual ~thread()
Definition paths.h:211
virtual label_text get_name(bool can_colorize) const =0
Definition sarif-sink.cc:769
Definition sarif-sink.h:151
Definition pretty-print.h:241
bool debug
Definition collect-utils.cc:34
static struct path_prefix cpath path
Definition collect2.cc:514
Definition diagnostics/context.h:39
Definition diagnostics/context.h:41
Definition event-id.h:64
int thread_id_t
Definition event-id.h:71
Definition coretypes.h:169
void dump_to_pp(pretty_printer *pp) const
Definition paths.cc:46
meaning(enum verb verb)
Definition paths.h:141
static const char * maybe_get_property_str(enum property)
Definition paths.cc:150
meaning()
Definition paths.h:135
meaning(enum verb verb, enum property property)
Definition paths.h:149
enum verb m_verb
Definition paths.h:160
enum property m_property
Definition paths.h:162
static const char * maybe_get_verb_str(enum verb)
Definition paths.cc:76
static const char * maybe_get_noun_str(enum noun)
Definition paths.cc:123
meaning(enum verb verb, enum noun noun)
Definition paths.h:145
enum noun m_noun
Definition paths.h:161
Definition function.h:249