/* Extensions to diagnostics::digraphs to support state graphs. Copyright (C) 2025 Free Software Foundation, Inc. Contributed by David Malcolm This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #ifndef GCC_DIAGNOSTICS_STATE_GRAPHS_H #define GCC_DIAGNOSTICS_STATE_GRAPHS_H #include "diagnostics/digraphs.h" #include "diagnostics/logical-locations.h" /* diagnostics::digraphs provides support for directed graphs. diagnostics::state_graphs provides a way to extend these graphs for representing "state graphs" i.e. a representation of the state of memory inside a program, for use e.g. by -fanalyzer. Specifically, nodes represent memory regions, and we use property bags in these nodes to stash extra properties (e.g. what kind of memory region a node is e.g. stack vs heap). */ class sarif_graph; namespace dot { class graph; } namespace diagnostics { namespace state_graphs { enum class node_kind { // Memory regions globals, code, function, // code within a particular function stack, stack_frame, heap_, thread_local_, /* Dynamically-allocated buffer, on heap or stack (depending on parent). */ dynalloc_buffer, variable, field, // field within a struct or union padding, // padding bits in a struct or union element, // element within an array other // anything else }; extern const char * node_kind_to_str (enum node_kind); enum class node_dynalloc_state { unknown, nonnull, unchecked, freed }; /* Prefixes to use in SARIF property bags. */ #define STATE_GRAPH_PREFIX "gcc/diagnostic_state_graph/" #define STATE_NODE_PREFIX "gcc/diagnostic_state_node/" #define STATE_EDGE_PREFIX "gcc/diagnostic_state_edge/" /* A wrapper around a node that gets/sets attributes, using the node's property bag for storage, so that the data roundtrips through SARIF. */ struct state_node_ref { state_node_ref (diagnostics::digraphs::node &node) : m_node (node) {} enum node_kind get_node_kind () const; void set_node_kind (enum node_kind); // For node_kind::stack_frame, this will be the function logical_locations::key get_logical_loc () const { return m_node.get_logical_loc (); } // For node_kind::dynalloc_buffer enum node_dynalloc_state get_dynalloc_state () const; void set_dynalloc_state (enum node_dynalloc_state) const; const char * get_dynamic_extents () const; const char * get_name () const { return get_attr ("name"); } void set_name (const char *name) const { set_attr ("name", name); } const char * get_type () const { return get_attr ("type"); } void set_type (const char *type) const { set_attr ("type", type); } const char * get_value () const { return get_attr ("value"); } const char * get_index () const { return get_attr ("index"); } const char * get_attr (const char *key) const { return m_node.get_attr (STATE_NODE_PREFIX, key); } void set_attr (const char *key, const char *value) const { return m_node.set_attr (STATE_NODE_PREFIX, key, value); } void set_json_attr (const char *key, std::unique_ptr value) const; diagnostics::digraphs::node &m_node; }; extern std::unique_ptr make_dot_graph (const diagnostics::digraphs::digraph &state_graph, const logical_locations::manager &logical_loc_mgr); } // namespace state_graphs } // namespace diagnostics #endif /* ! GCC_DIAGNOSTICS_STATE_GRAPHS_H */