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. */
101 enum class noun
102 {
104
106 sensitive, // this one isn't in SARIF v2.1.0; filed as https://github.com/oasis-tcs/sarif-spec/issues/530
111 };
112 enum class property
113 {
115
118 };
119 /* A bundle of such enums, allowing for descriptions of the meaning of
120 an event, such as
121 - "acquire memory": meaning (verb::acquire, noun::memory)
122 - "take true branch"": meaning (verb::branch, property::true)
123 - "return from function": meaning (verb::return, noun::function)
124 etc, as per SARIF's threadFlowLocation "kinds" property
125 (SARIF v2.1.0 section 3.38.8). */
126 struct meaning
127 {
129 : m_verb (verb::unknown),
132 {
133 }
134 meaning (enum verb verb, enum noun noun)
136 {
137 }
142
143 void dump_to_pp (pretty_printer *pp) const;
144
145 static const char *maybe_get_verb_str (enum verb);
146 static const char *maybe_get_noun_str (enum noun);
147 static const char *maybe_get_property_str (enum property);
148
151 enum property m_property;
152 };
153
154 virtual ~event () {}
155
156 virtual location_t get_location () const = 0;
157
158 /* Stack depth, so that consumers can visualize the interprocedural
159 calls, returns, and frame nesting. */
160 virtual int get_stack_depth () const = 0;
161
162 /* Print a localized (and possibly colorized) description of this event. */
163 virtual void print_desc (pretty_printer &pp) const = 0;
164
165 /* Get a logical location for this event, or null if there is none. */
167
168 virtual meaning get_meaning () const = 0;
169
170 /* True iff we should draw a line connecting this event to the
171 next event (e.g. to highlight control flow). */
172 virtual bool connect_to_next_event_p () const = 0;
173
174 virtual thread_id_t get_thread_id () const = 0;
175
176 /* Hook for SARIF output to allow for adding diagnostic-specific
177 properties to the threadFlowLocation object's property bag. */
178 virtual void
180 sarif_object &/*thread_flow_loc_obj*/) const
181 {
182 }
183
184 /* Hook for capturing state at this event, potentially for visualizing
185 in HTML output, or for adding to SARIF. */
186 virtual std::unique_ptr<digraphs::digraph>
188
189 label_text get_desc (pretty_printer &ref_pp) const;
190};
191
192/* Abstract base class representing a thread of execution within
193 a diagnostics::paths::path.
194 Each event is associated with one thread.
195 Typically there is just one thread per diagnostics::paths::path. */
196
198{
199public:
200 virtual ~thread () {}
201 virtual label_text get_name (bool can_colorize) const = 0;
202};
203
204/* Abstract base class for getting at a sequence of events. */
205
206class path
207{
208 public:
209 virtual ~path () {}
210 virtual unsigned num_events () const = 0;
211 virtual const event & get_event (int idx) const = 0;
212 virtual unsigned num_threads () const = 0;
213 virtual const thread &
215
216 /* Return true iff the two events are both within the same function,
217 or both outside of any function. */
218 virtual bool
219 same_function_p (int event_idx_a,
220 int event_idx_b) const = 0;
221
222 bool interprocedural_p () const;
223 bool multithreaded_p () const;
224
229
230protected:
231 path (const logical_locations::manager &logical_loc_mgr)
232 : m_logical_loc_mgr (logical_loc_mgr)
233 {
234 }
235
236private:
237 bool get_first_event_in_a_function (unsigned *out_idx) const;
238
240};
241
242} // namespace paths
243} // namespace diagnostics
244
245/* Concrete subclasses of the above can be found in
246 simple-diagnostic-path.h. */
247
248extern void debug (diagnostics::paths::path *path);
249
250#endif /* ! GCC_DIAGNOSTICS_PATHS_H */
Definition digraphs.h:88
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:179
virtual int get_stack_depth() const =0
verb
Definition paths.h:88
@ release
Definition paths.h:92
@ call
Definition paths.h:95
@ 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
@ 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:165
virtual thread_id_t get_thread_id() const =0
property
Definition paths.h:113
@ true_
Definition paths.h:116
@ false_
Definition paths.h:117
noun
Definition paths.h:102
@ taint
Definition paths.h:105
@ sensitive
Definition paths.h:106
@ resource
Definition paths.h:110
@ function
Definition paths.h:107
@ memory
Definition paths.h:109
@ lock
Definition paths.h:108
virtual ~event()
Definition paths.h:154
label_text get_desc(pretty_printer &ref_pp) const
Definition paths.cc:154
virtual meaning get_meaning() const =0
Definition paths.h:207
bool interprocedural_p() const
Definition paths.cc:200
const logical_locations::manager & m_logical_loc_mgr
Definition paths.h:239
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:180
path(const logical_locations::manager &logical_loc_mgr)
Definition paths.h:231
virtual ~path()
Definition paths.h:209
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:225
Definition paths.h:198
virtual ~thread()
Definition paths.h:200
virtual label_text get_name(bool can_colorize) const =0
Definition sarif-sink.cc:762
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:167
void dump_to_pp(pretty_printer *pp) const
Definition paths.cc:47
static const char * maybe_get_property_str(enum property)
Definition paths.cc:135
meaning()
Definition paths.h:128
meaning(enum verb verb, enum property property)
Definition paths.h:138
enum verb m_verb
Definition paths.h:149
enum property m_property
Definition paths.h:151
static const char * maybe_get_verb_str(enum verb)
Definition paths.cc:77
static const char * maybe_get_noun_str(enum noun)
Definition paths.cc:108
meaning(enum verb verb, enum noun noun)
Definition paths.h:134
enum noun m_noun
Definition paths.h:150