Branch data Line data Source code
1 : : /* Extensions to diagnostics::digraphs to support state graphs.
2 : : Copyright (C) 2025 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
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/>. */
20 : :
21 : : #ifndef GCC_DIAGNOSTICS_STATE_GRAPHS_H
22 : : #define GCC_DIAGNOSTICS_STATE_GRAPHS_H
23 : :
24 : : #include "diagnostics/digraphs.h"
25 : : #include "diagnostics/logical-locations.h"
26 : :
27 : : /* diagnostics::digraphs provides support for directed graphs.
28 : :
29 : : diagnostics::state_graphs provides a way to extend these graphs
30 : : for representing "state graphs" i.e. a representation of the state
31 : : of memory inside a program, for use e.g. by -fanalyzer.
32 : :
33 : : Specifically, nodes represent memory regions, and we use property bags
34 : : in these nodes to stash extra properties (e.g. what kind of memory region
35 : : a node is e.g. stack vs heap). */
36 : :
37 : : class sarif_graph;
38 : : namespace dot { class graph; }
39 : :
40 : : namespace diagnostics {
41 : : namespace state_graphs {
42 : :
43 : : enum class node_kind
44 : : {
45 : : // Memory regions
46 : : globals,
47 : : code,
48 : : function, // code within a particular function
49 : : stack,
50 : : stack_frame,
51 : : heap_,
52 : : thread_local_,
53 : :
54 : : /* Dynamically-allocated buffer,
55 : : on heap or stack (depending on parent). */
56 : : dynalloc_buffer,
57 : :
58 : : variable,
59 : :
60 : : field, // field within a struct or union
61 : : padding, // padding bits in a struct or union
62 : : element, // element within an array
63 : :
64 : : other // anything else
65 : : };
66 : :
67 : : extern const char *
68 : : node_kind_to_str (enum node_kind);
69 : :
70 : : enum class node_dynalloc_state
71 : : {
72 : : unknown,
73 : : nonnull,
74 : : unchecked,
75 : : freed
76 : : };
77 : :
78 : : /* Prefixes to use in SARIF property bags. */
79 : : #define STATE_GRAPH_PREFIX "gcc/diagnostic_state_graph/"
80 : : #define STATE_NODE_PREFIX "gcc/diagnostic_state_node/"
81 : : #define STATE_EDGE_PREFIX "gcc/diagnostic_state_edge/"
82 : :
83 : : /* A wrapper around a node that gets/sets attributes, using
84 : : the node's property bag for storage, so that the data roundtrips
85 : : through SARIF. */
86 : :
87 : : struct state_node_ref
88 : : {
89 : 213 : state_node_ref (diagnostics::digraphs::node &node)
90 : 1218 : : m_node (node)
91 : : {}
92 : :
93 : : enum node_kind
94 : : get_node_kind () const;
95 : : void
96 : : set_node_kind (enum node_kind);
97 : :
98 : : // For node_kind::stack_frame, this will be the function
99 : : logical_locations::key
100 : 1 : get_logical_loc () const
101 : : {
102 : 1 : return m_node.get_logical_loc ();
103 : : }
104 : :
105 : : // For node_kind::dynalloc_buffer
106 : : enum node_dynalloc_state
107 : : get_dynalloc_state () const;
108 : :
109 : : void
110 : : set_dynalloc_state (enum node_dynalloc_state) const;
111 : :
112 : : const char *
113 : : get_dynamic_extents () const;
114 : :
115 : : const char *
116 : 4 : get_name () const { return get_attr ("name"); }
117 : : void
118 : 57 : set_name (const char *name) const { set_attr ("name", name); }
119 : :
120 : : const char *
121 : 16 : get_type () const { return get_attr ("type"); }
122 : : void
123 : 278 : set_type (const char *type) const { set_attr ("type", type); }
124 : :
125 : : const char *
126 : 8 : get_value () const { return get_attr ("value"); }
127 : :
128 : : const char *
129 : 4 : get_index () const { return get_attr ("index"); }
130 : :
131 : : const char *
132 : 60 : get_attr (const char *key) const
133 : : {
134 : 60 : return m_node.get_attr (STATE_NODE_PREFIX, key);
135 : : }
136 : :
137 : : void
138 : 1311 : set_attr (const char *key, const char *value) const
139 : : {
140 : 1311 : return m_node.set_attr (STATE_NODE_PREFIX, key, value);
141 : : }
142 : :
143 : : void
144 : : set_json_attr (const char *key, std::unique_ptr<json::value> value) const;
145 : :
146 : : diagnostics::digraphs::node &m_node;
147 : : };
148 : :
149 : : extern std::unique_ptr<dot::graph>
150 : : make_dot_graph (const diagnostics::digraphs::digraph &state_graph,
151 : : const logical_locations::manager &logical_loc_mgr);
152 : :
153 : : } // namespace state_graphs
154 : : } // namespace diagnostics
155 : :
156 : : #endif /* ! GCC_DIAGNOSTICS_STATE_GRAPHS_H */
|