diff options
Diffstat (limited to 'gcc/analyzer')
-rw-r--r-- | gcc/analyzer/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/analyzer/ana-state-to-diagnostic-state.cc | 166 | ||||
-rw-r--r-- | gcc/analyzer/ana-state-to-diagnostic-state.h | 23 | ||||
-rw-r--r-- | gcc/analyzer/checker-event.cc | 9 | ||||
-rw-r--r-- | gcc/analyzer/sm-malloc.cc | 29 |
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 ®) { auto existing = m_region_to_state_node_map.find (®); 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[®] = &ref.m_node; - return ref; + auto &state_node = create_and_add_state_node (reg); + m_region_to_state_node_map[®] = &state_node; + return state_node; } -state_node_ref +diagnostics::digraphs::node & analyzer_state_graph::create_and_add_state_node (const region ®) { 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 ®) 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 ®, - 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 ®) 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 ®) 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 ®) 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 ®, 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 ®, 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 (®, 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 ®, - state_node_ref node_ref) +analyzer_state_graph:: +set_attr_for_dynamic_extents (const region ®, + diagnostics::digraphs::node &state_node) { const svalue *sval = m_state.m_region_model->get_dynamic_extents (®); if (sval) @@ -642,15 +659,16 @@ analyzer_state_graph::set_attr_for_dynamic_extents (const region ®, 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 ®, - 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 ®); 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 ®); 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 ®, - 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 ®); @@ -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 ®, const concrete_bindings_t &conc_bindings, bool create_all); void set_attr_for_dynamic_extents (const region ®, - diagnostics::state_graphs::state_node_ref); + diagnostics::digraphs::node &); bool show_child_state_node_for_child_region_p (const region ®, @@ -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 ®_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); } } |