aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/analyzer')
-rw-r--r--gcc/analyzer/ChangeLog9
-rw-r--r--gcc/analyzer/ana-state-to-diagnostic-state.cc166
-rw-r--r--gcc/analyzer/ana-state-to-diagnostic-state.h23
-rw-r--r--gcc/analyzer/checker-event.cc9
-rw-r--r--gcc/analyzer/sm-malloc.cc29
5 files changed, 135 insertions, 101 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index a613dc5..3de38b2 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,12 @@
+2025-10-16 David Malcolm <dmalcolm@redhat.com>
+
+ * ana-state-to-diagnostic-state.cc: Reimplement throughout to use
+ json::property instances found within custom_sarif_properties
+ throughout, rather than types in diagnostics::state_graphs.
+ * ana-state-to-diagnostic-state.h: Likewise.
+ * checker-event.cc: Likewise.
+ * sm-malloc.cc: Likewise.
+
2025-10-09 David Malcolm <dmalcolm@redhat.com>
* access-diagram.cc: Update for renaming of fields of binding_key.
diff --git a/gcc/analyzer/ana-state-to-diagnostic-state.cc b/gcc/analyzer/ana-state-to-diagnostic-state.cc
index 25e66a0..3574036 100644
--- a/gcc/analyzer/ana-state-to-diagnostic-state.cc
+++ b/gcc/analyzer/ana-state-to-diagnostic-state.cc
@@ -39,38 +39,55 @@ along with GCC; see the file COPYING3. If not see
namespace ana {
-using namespace ::diagnostics::state_graphs;
+namespace node_properties = custom_sarif_properties::state_graphs::node;
static void
-set_wi_attr (state_node_ref state_node,
- const char *attr_name,
+set_wi_attr (diagnostics::digraphs::node &state_node,
+ const json::string_property &property,
const wide_int_ref &w,
signop sgn)
{
pretty_printer pp;
pp_wide_int (&pp, w, sgn);
- state_node.set_attr (attr_name, pp_formatted_text (&pp));
+ state_node.set_property (property, pp_formatted_text (&pp));
}
static void
-set_type_attr (state_node_ref state_node, const_tree type)
+set_type_attr (diagnostics::digraphs::node &state_node,
+ const_tree type)
{
gcc_assert (type);
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%T", type);
- state_node.set_type (pp_formatted_text (&pp));
+ state_node.set_property (node_properties::type,
+ pp_formatted_text (&pp));
}
static void
-set_bits_attr (state_node_ref state_node,
+set_bits_attr (diagnostics::digraphs::node & state_node,
bit_range bits)
{
pretty_printer pp;
bits.dump_to_pp (&pp);
- state_node.set_attr ("bits", pp_formatted_text (&pp));
+ state_node.set_property (node_properties::bits,
+ pp_formatted_text (&pp));
}
+static void
+set_value_attrs (diagnostics::digraphs::node &state_node,
+ const svalue &sval)
+{
+ state_node.set_property (node_properties::value,
+ sval.to_json ());
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ sval.dump_to_pp (&pp, true);
+ state_node.set_property (node_properties::value_str,
+ pp_formatted_text (&pp));
+}
+
+
// class analyzer_state_graph : public diagnostics::digraphs::digraph
analyzer_state_graph::analyzer_state_graph (const program_state &state,
@@ -141,34 +158,34 @@ analyzer_state_graph::analyzer_state_graph (const program_state &state,
/* Ensure we have a node for the dst region. This
could lead to additional pending edges. */
- auto dst_node = get_or_create_state_node (item.m_dst_reg);
- add_edge (nullptr, item.m_src_node.m_node, dst_node.m_node);
+ auto &dst_node = get_or_create_state_node (item.m_dst_reg);
+ add_edge (nullptr, item.m_src_node, dst_node);
}
}
-state_node_ref
+diagnostics::digraphs::node &
analyzer_state_graph::get_or_create_state_node (const region &reg)
{
auto existing = m_region_to_state_node_map.find (&reg);
if (existing != m_region_to_state_node_map.end ())
return *existing->second;
- auto ref = create_and_add_state_node (reg);
- m_region_to_state_node_map[&reg] = &ref.m_node;
- return ref;
+ auto &state_node = create_and_add_state_node (reg);
+ m_region_to_state_node_map[&reg] = &state_node;
+ return state_node;
}
-state_node_ref
+diagnostics::digraphs::node &
analyzer_state_graph::create_and_add_state_node (const region &reg)
{
auto node = create_state_node (reg);
- state_node_ref result = *node;
+ diagnostics::digraphs::node &result = *node;
if (auto parent_reg = reg.get_parent_region ())
if (parent_reg->get_kind () != RK_ROOT)
{
- auto parent_state_node = get_or_create_state_node (*parent_reg);
- parent_state_node.m_node.add_child (std::move (node));
+ auto &parent_state_node = get_or_create_state_node (*parent_reg);
+ parent_state_node.add_child (std::move (node));
return result;
}
add_node (std::move (node));
@@ -264,19 +281,18 @@ analyzer_state_graph::make_node_id (const region &reg)
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::
-make_state_node (diagnostics::state_graphs::node_kind kind,
+make_state_node (enum node_properties::kind_t kind,
std::string id)
{
auto node = std::make_unique<diagnostics::digraphs::node> (*this, std::move (id));
- state_node_ref node_ref (*node);
- node_ref.set_node_kind (kind);
+ node->set_property (node_properties::kind_prop, kind);
return node;
}
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::
make_memspace_state_node (const region &reg,
- diagnostics::state_graphs::node_kind kind)
+ enum node_properties::kind_t kind)
{
return make_state_node (kind, make_node_id (reg));
}
@@ -296,7 +312,7 @@ analyzer_state_graph::create_state_node (const region &reg)
const frame_region &frame_reg
= static_cast<const frame_region &> (reg);
- node = make_state_node (diagnostics::state_graphs::node_kind::stack_frame,
+ node = make_state_node (node_properties::kind_t::stack_frame,
make_node_id (reg));
node->set_logical_loc
(m_logical_loc_mgr.key_from_tree (frame_reg.get_fndecl ()));
@@ -304,58 +320,59 @@ analyzer_state_graph::create_state_node (const region &reg)
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%E", frame_reg.get_fndecl ());
- node->set_attr (STATE_NODE_PREFIX, "function",
- pp_formatted_text (&pp));
+ node->set_property (node_properties::function,
+ pp_formatted_text (&pp));
}
}
break;
case RK_GLOBALS:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::globals);
+ node_properties::kind_t::globals);
break;
case RK_CODE:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::code);
+ node_properties::kind_t::code);
break;
case RK_FUNCTION:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::function);
+ node_properties::kind_t::function);
// TODO
break;
case RK_STACK:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::stack);
+ node_properties::kind_t::stack);
break;
case RK_HEAP:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::heap_);
+ node_properties::kind_t::heap_);
break;
case RK_THREAD_LOCAL:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::thread_local_);
+ node_properties::kind_t::thread_local_);
break;
case RK_ROOT:
gcc_unreachable ();
break;
case RK_SYMBOLIC:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::other);
+ node_properties::kind_t::other);
break;
case RK_DECL:
{
- node = make_state_node (diagnostics::state_graphs::node_kind::variable,
+ node = make_state_node (node_properties::kind_t::variable,
make_node_id (reg));
const decl_region &decl_reg
= static_cast<const decl_region &> (reg);
- state_node_ref node_ref (*node);
+
{
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%E", decl_reg.get_decl ());
- node_ref.set_name (pp_formatted_text (&pp));
+ node->set_property (node_properties::name,
+ pp_formatted_text (&pp));
}
set_type_attr (*node, TREE_TYPE (decl_reg.get_decl ()));
}
@@ -377,14 +394,15 @@ analyzer_state_graph::create_state_node (const region &reg)
case RK_ERRNO:
case RK_PRIVATE:
case RK_UNKNOWN:
- node = make_state_node (diagnostics::state_graphs::node_kind::other,
+ node = make_state_node (node_properties::kind_t::other,
make_node_id (reg));
break;
case RK_HEAP_ALLOCATED:
case RK_ALLOCA:
- node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::dynalloc_buffer);
+ node
+ = make_memspace_state_node (reg,
+ node_properties::kind_t::dynalloc_buffer);
set_attr_for_dynamic_extents (reg, *node);
break;
}
@@ -425,9 +443,9 @@ create_state_nodes_for_binding_cluster (const binding_cluster &cluster,
get_or_create_state_node (*reg);
}
- auto ref = get_or_create_state_node (*cluster.get_base_region ());
+ auto &ref = get_or_create_state_node (*cluster.get_base_region ());
- ref.m_node.add_child (create_state_node_for_conc_bindings (conc_bindings));
+ ref.add_child (create_state_node_for_conc_bindings (conc_bindings));
const region *typed_reg = cluster.get_base_region ();
if (!typed_reg->get_type ())
@@ -455,23 +473,18 @@ create_state_nodes_for_binding_cluster (const binding_cluster &cluster,
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::create_state_node_for_conc_bindings (const concrete_bindings_t &conc_bindings)
{
- auto node = make_state_node (diagnostics::state_graphs::node_kind::other,
+ auto node = make_state_node (node_properties::kind_t::other,
make_node_id ("concrete-bindings"));
for (auto iter : conc_bindings)
{
const bit_range bits = iter.first;
const svalue *sval = iter.second;
auto binding_state_node
- = make_state_node (diagnostics::state_graphs::node_kind::other,
+ = make_state_node (node_properties::kind_t::other,
make_node_id ("binding"));
set_bits_attr (*binding_state_node, bits);
- {
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- sval->dump_to_pp (&pp, true);
- binding_state_node->set_attr (STATE_NODE_PREFIX, "value",
- pp_formatted_text (&pp));
- }
+ gcc_assert (sval);
+ set_value_attrs (*binding_state_node, *sval);
node->add_child (std::move (binding_state_node));
}
return node;
@@ -496,27 +509,28 @@ analyzer_state_graph::get_bit_range_within_base_region (const region &reg,
void
analyzer_state_graph::
-populate_state_node_for_typed_region (state_node_ref node,
+populate_state_node_for_typed_region (diagnostics::digraphs::node &state_node,
const region &reg,
const concrete_bindings_t &conc_bindings,
bool create_all)
{
const_tree reg_type = reg.get_type ();
gcc_assert (reg_type);
- set_type_attr (node, reg_type);
+ set_type_attr (state_node, reg_type);
bit_range bits (0, 0);
if (get_bit_range_within_base_region (reg, bits))
{
- set_bits_attr (node, bits);
+ set_bits_attr (state_node, bits);
auto search = conc_bindings.find (bits);
if (search != conc_bindings.end ())
{
const svalue *bound_sval = search->second;
- node.set_json_attr ("value", bound_sval->to_json ());
+ gcc_assert (bound_sval);
+ set_value_attrs (state_node, *bound_sval);
if (const region *dst_reg = bound_sval->maybe_get_region ())
- m_pending_edges.push_back ({node, *dst_reg});
+ m_pending_edges.push_back ({state_node, *dst_reg});
}
}
@@ -555,9 +569,10 @@ populate_state_node_for_typed_region (state_node_ref node,
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::element,
+ (node_properties::kind_t::element,
make_node_id (*child_reg));
- set_wi_attr (*child_state_node, "index", idx, UNSIGNED);
+ set_wi_attr (*child_state_node,
+ node_properties::index, idx, UNSIGNED);
// Recurse:
gcc_assert (element_type);
@@ -565,7 +580,7 @@ populate_state_node_for_typed_region (state_node_ref node,
*child_reg,
conc_bindings,
create_all);
- node.m_node.add_child (std::move (child_state_node));
+ state_node.add_child (std::move (child_state_node));
}
}
}
@@ -587,11 +602,12 @@ populate_state_node_for_typed_region (state_node_ref node,
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::padding,
+ (node_properties::kind_t::padding,
make_node_id (*child_reg));
- set_wi_attr (*child_state_node, "num_bits",
+ set_wi_attr (*child_state_node,
+ node_properties::num_bits,
item.m_bit_range.m_size_in_bits, SIGNED);
- node.m_node.add_child (std::move (child_state_node));
+ state_node.add_child (std::move (child_state_node));
}
}
else
@@ -600,27 +616,27 @@ populate_state_node_for_typed_region (state_node_ref node,
= m_mgr.get_field_region (&reg,
const_cast<tree> (item.m_field));
if (show_child_state_node_for_child_region_p (*child_reg,
- conc_bindings,
- create_all))
+ conc_bindings,
+ create_all))
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::field,
+ (node_properties::kind_t::field,
make_node_id (*child_reg));
{
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%D", item.m_field);
- child_state_node->set_attr (STATE_NODE_PREFIX, "name",
- pp_formatted_text (&pp));
+ child_state_node->set_property (node_properties::name,
+ pp_formatted_text (&pp));
}
// Recurse:
populate_state_node_for_typed_region (*child_state_node,
- *child_reg,
- conc_bindings,
- create_all);
- node.m_node.add_child (std::move (child_state_node));
+ *child_reg,
+ conc_bindings,
+ create_all);
+ state_node.add_child (std::move (child_state_node));
}
}
}
@@ -630,8 +646,9 @@ populate_state_node_for_typed_region (state_node_ref node,
}
void
-analyzer_state_graph::set_attr_for_dynamic_extents (const region &reg,
- state_node_ref node_ref)
+analyzer_state_graph::
+set_attr_for_dynamic_extents (const region &reg,
+ diagnostics::digraphs::node &state_node)
{
const svalue *sval = m_state.m_region_model->get_dynamic_extents (&reg);
if (sval)
@@ -642,15 +659,16 @@ analyzer_state_graph::set_attr_for_dynamic_extents (const region &reg,
pp_wide_int (&pp, wi::to_wide (cst), UNSIGNED);
else
sval->dump_to_pp (&pp, true);
- node_ref.set_attr ("dynamic-extents", pp_formatted_text (&pp));
+ state_node.set_property (state_node_properties::dynamic_extents,
+ pp_formatted_text (&pp));
}
}
bool
analyzer_state_graph::
show_child_state_node_for_child_region_p (const region &reg,
- const concrete_bindings_t &conc_bindings,
- bool create_all)
+ const concrete_bindings_t &conc_bindings,
+ bool create_all)
{
if (create_all)
return true;
diff --git a/gcc/analyzer/ana-state-to-diagnostic-state.h b/gcc/analyzer/ana-state-to-diagnostic-state.h
index 3a5ccc1..272a4d7 100644
--- a/gcc/analyzer/ana-state-to-diagnostic-state.h
+++ b/gcc/analyzer/ana-state-to-diagnostic-state.h
@@ -23,34 +23,38 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostics/state-graphs.h"
#include "tree-logical-location.h"
+#include "custom-sarif-properties/state-graphs.h"
namespace ana {
+namespace state_node_properties = custom_sarif_properties::state_graphs::node;
+
class analyzer_state_graph : public diagnostics::digraphs::digraph
{
public:
analyzer_state_graph (const program_state &state,
const extrinsic_state &ext_state);
- diagnostics::state_graphs::state_node_ref
+ diagnostics::digraphs::node &
get_or_create_state_node (const region &reg);
private:
+
struct pending_edge
{
- diagnostics::state_graphs::state_node_ref m_src_node;
+ diagnostics::digraphs::node & m_src_node;
const region &m_dst_reg;
};
-
- diagnostics::state_graphs::state_node_ref
+
+ diagnostics::digraphs::node &
create_and_add_state_node (const region &reg);
std::unique_ptr<diagnostics::digraphs::node>
- make_state_node (diagnostics::state_graphs::node_kind kind,
+ make_state_node (enum state_node_properties::kind_t kind,
std::string id);
std::unique_ptr<diagnostics::digraphs::node>
make_memspace_state_node (const region &reg,
- enum diagnostics::state_graphs::node_kind kind);
+ enum state_node_properties::kind_t kind);
std::unique_ptr<diagnostics::digraphs::node>
create_state_node (const region &reg);
@@ -71,14 +75,14 @@ private:
bit_range &out);
void
- populate_state_node_for_typed_region (diagnostics::state_graphs::state_node_ref,
+ populate_state_node_for_typed_region (diagnostics::digraphs::node &,
const region &reg,
const concrete_bindings_t &conc_bindings,
bool create_all);
void
set_attr_for_dynamic_extents (const region &reg,
- diagnostics::state_graphs::state_node_ref);
+ diagnostics::digraphs::node &);
bool
show_child_state_node_for_child_region_p (const region &reg,
@@ -95,7 +99,8 @@ private:
const program_state &m_state;
const extrinsic_state &m_ext_state;
region_model_manager &m_mgr;
- std::map<const region *, diagnostics::digraphs::node *> m_region_to_state_node_map;
+ std::map<const region *,
+ diagnostics::digraphs::node *> m_region_to_state_node_map;
std::map<const region *, tree> m_types_for_untyped_regions;
unsigned m_next_id;
std::vector<pending_edge> m_pending_edges;
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 4eac945..790ebc7 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-logical-location.h"
#include "diagnostics/sarif-sink.h"
#include "diagnostics/state-graphs.h"
+#include "custom-sarif-properties/state-graphs.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
@@ -242,9 +243,11 @@ checker_event::maybe_make_diagnostic_state_graph (bool debug) const
pretty_printer pp;
text_art::theme *theme = global_dc->get_diagram_theme ();
text_art::dump_to_pp (*state, theme, &pp);
- result->set_attr (STATE_GRAPH_PREFIX,
- "analyzer/program_state/",
- pp_formatted_text (&pp));
+ const json::string_property program_state_property
+ (custom_sarif_properties::state_graphs::graph::prefix,
+ "analyzer/program_state/");
+ result->set_property (program_state_property,
+ pp_formatted_text (&pp));
}
return result;
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index a6b1421..8ce7710 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -2735,7 +2735,7 @@ malloc_state_machine::transition_ptr_sval_non_null (region_model *model,
smap->set_state (model, new_ptr_sval, m_free.m_nonnull, nullptr, ext_state);
}
-static enum diagnostics::state_graphs::node_dynalloc_state
+static enum custom_sarif_properties::state_graphs::node::dynalloc_state_t
get_dynalloc_state_for_state (enum resource_state rs)
{
switch (rs)
@@ -2746,17 +2746,17 @@ get_dynalloc_state_for_state (enum resource_state rs)
case RS_NULL:
case RS_NON_HEAP:
case RS_STOP:
- return diagnostics::state_graphs::node_dynalloc_state::unknown;
+ return state_node_properties::dynalloc_state_t::unknown;
case RS_ASSUMED_NON_NULL:
- return diagnostics::state_graphs::node_dynalloc_state::nonnull;
+ return state_node_properties::dynalloc_state_t::nonnull;
case RS_UNCHECKED:
- return diagnostics::state_graphs::node_dynalloc_state::unchecked;
+ return state_node_properties::dynalloc_state_t::unchecked;
case RS_NONNULL:
- return diagnostics::state_graphs::node_dynalloc_state::nonnull;
+ return state_node_properties::dynalloc_state_t::nonnull;
case RS_FREED:
- return diagnostics::state_graphs::node_dynalloc_state::freed;
+ return state_node_properties::dynalloc_state_t::freed;
}
}
@@ -2768,24 +2768,23 @@ add_state_to_state_graph (analyzer_state_graph &out_state_graph,
{
if (const region *reg = sval.maybe_get_region ())
{
- auto reg_node = out_state_graph.get_or_create_state_node (*reg);
+ auto &reg_node = out_state_graph.get_or_create_state_node (*reg);
auto alloc_state = as_a_allocation_state (state);
gcc_assert (alloc_state);
- reg_node.set_dynalloc_state
- (get_dynalloc_state_for_state (alloc_state->m_rs));
+ reg_node.set_property (state_node_properties::dynalloc_state_prop,
+ get_dynalloc_state_for_state (alloc_state->m_rs));
+
if (alloc_state->m_deallocators)
{
pretty_printer pp;
alloc_state->m_deallocators->dump_to_pp (&pp);
- reg_node.m_node.set_attr (STATE_NODE_PREFIX,
- "expected-deallocators",
- pp_formatted_text (&pp));
+ reg_node.set_property (state_node_properties::expected_deallocators,
+ pp_formatted_text (&pp));
}
if (alloc_state->m_deallocator)
- reg_node.m_node.set_attr (STATE_NODE_PREFIX,
- "deallocator",
- alloc_state->m_deallocator->m_name);
+ reg_node.set_property (state_node_properties::deallocator,
+ alloc_state->m_deallocator->m_name);
}
}