diff options
68 files changed, 2161 insertions, 529 deletions
@@ -1,3 +1,8 @@ +2025-10-15 Basil Milanich <bmilanich@gmail.com> + + * Makefile.tpl (distclean): Remove extraenous semicolon. + * Makefile.in: Rebuilt. + 2025-10-11 Ben Boeckel <ben.boeckel@kitware.com> * config-ml.in: Update patch email address. diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 55737ce..8a1d884 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2025-10-16 David Malcolm <dmalcolm@redhat.com> + + * gcc.doxy (INPUT): Add gcc/custom-sarif-properties + 2025-10-08 Jakub Jelinek <jakub@redhat.com> * unicode/README: Add HangulSyllableType.txt file to the diff --git a/contrib/gcc.doxy b/contrib/gcc.doxy index 1595204..56e3845 100644 --- a/contrib/gcc.doxy +++ b/contrib/gcc.doxy @@ -478,7 +478,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = gcc gcc/analyzer gcc/diagnostics gcc/text-art +INPUT = gcc gcc/analyzer gcc/custom-sarif-properties gcc/diagnostics gcc/text-art # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a7cb97..b2def9f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,251 @@ +2025-10-16 David Malcolm <dmalcolm@redhat.com> + + * Makefile.in (OBJS-libcommon): Add + custom-sarif-properties/digraphs.o and + custom-sarif-properties/state-graphs.o. Remove + diagnostics/state-graphs.o. + * configure: Regenerate. + * configure.ac: Add custom-sarif-properties to subdir iteration. + * custom-sarif-properties/digraphs.cc: New file. + * custom-sarif-properties/digraphs.h: New file. + * custom-sarif-properties/state-graphs.cc: New file. + * custom-sarif-properties/state-graphs.h: New file. + * diagnostics/diagnostics-selftests.cc + (run_diagnostics_selftests): Drop call of state_graphs_cc_tests. + * diagnostics/diagnostics-selftests.h (state_graphs_cc_tests): + Delete decl. + * diagnostics/digraphs.cc: Include + "custom-sarif-properties/digraphs.h". Move include of + "selftest.h" to within CHECKING_P section. + (using digraph_object): New. + (namespace properties): New. + (diagnostics::digraphs::object::get_attr): Delete. + (diagnostics::digraphs::object::set_attr): Delete. + (diagnostics::digraphs::object::set_json_attr): Delete. + (digraph_object::get_property): New definitions, for various + property types. + (digraph_object::set_property): Likewise. + (digraph_object::maybe_get_property): New. + (digraph_object::get_property_as_tristate): New. + (digraph_object::ensure_property_bag): New. + (digraph::get_graph_kind): New. + (digraph::set_graph_kind): New. + Add include of "custom-sarif-properties/state-graphs.h". + (selftest::test_simple_graph): Rewrite to use json::property + instances rather than string attribute names. + (selftest::test_property_objects): New test. + (selftest::digraphs_cc_tests): Call it. + * diagnostics/digraphs.h: Include "tristate.h". + (object::get_attr): Delete. + (object::set_attr): Delete. + (object::get_property): New decls. + (object::set_property): New decls. + (object::maybe_get_property): New. + (object::get_property_as_tristate): New. + (object::set_json_attr): Delete. + (object::ensure_property_bag): New. + (graph::get_graph_kind): New. + (graph::set_graph_kind): New. + * diagnostics/html-sink.cc + (html_generation_options::html_generation_options): Update for + field renamings. + (html_generation_options::dump): Likewise. + (html_builder::maybe_make_state_diagram): Likewise. + (html_builder::add_graph): Show SARIF and .dot src inline, if + requested. + * diagnostics/html-sink.h + (html_generation_options::m_show_state_diagrams_sarif): Rename + to... + (html_generation_options::m_show_graph_sarif): ...this. + (html_generation_options::m_show_state_diagrams_dot_src): Rename + to... + (html_generation_options::m_show_graph_dot_src0): ...this. + * diagnostics/output-spec.cc + (html_scheme_handler::maybe_handle_kv): Rename keys. + (html_scheme_handler::get_keys): Likewise. + * diagnostics/state-graphs-to-dot.cc: : Reimplement throughout to + use json::property instances found within custom_sarif_properties + throughout, rather than types in diagnostics::state_graphs. + * diagnostics/state-graphs.cc: Deleted file. + * diagnostics/state-graphs.h: Delete almost all, except decl of + diagnostics::state_graphs::make_dot_graph. + * doc/invoke.texi: Update for changes to "experimental-html" sink + keys. + * json.cc (json::object::set_string): New. + (json::object::set_integer): New. + (json::object::set_bool): New. + (json::object::set_array_of_string): New. + * json.h: Include "label-text.h". + (struct json::property): New template. + (json::string_property): New. + (json::integer_property): New. + (json::bool_property): New. + (json::json_property): New. + (using json::array_of_string_property): New. + (struct json::enum_traits): New. + (enum_json::property): New. + (json::value::dyn_cast_array): New vfunc. + (json::value::dyn_cast_integer_number): New vfunc. + (json::value::set_string): New. + (json::value::set_integer): New. + (json::value::set_bool): New. + (json::value::set_array_of_string): New. + (json::value::maybe_get_enum): New. + (json::value::set_enum): New. + (json::array::dyn_cast_array): New. + (json::integer_number::dyn_cast_integer_number): New. + (object::maybe_get_enum): New. + (object::set_enum): New. + +2025-10-16 Ayappan Perumal <ayappap2@in.ibm.com> + + * config/rs6000/aix.h (SUBTARGET_DRIVER_SELF_SPECS): + Error out when stack-protector option is used in AIX + as it is not supported on AIX + Approved By: Segher Boessenkool <segher@kernel.crashing.org> + +2025-10-16 Richard Biener <rguenther@suse.de> + + PR tree-optimization/122292 + * tree-vect-loop.cc (vect_transform_reduction): Compute the + input vector type the same way the analysis phase does. + +2025-10-15 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/121468 + PR tree-optimization/121206 + PR tree-optimization/122200 + * value-range.cc (irange_bitmask::range_from_mask): New. + (irange::snap): Add explicit overflow flag. + (irange::snap_subranges): Use overflow flag. + (irange::set_range_from_bitmask): Use range_from_mask. + (test_irange_snap_bounds): Adjust for improved ranges. + * value-range.h (irange::range_from_mask): Add prototype. + (irange::snap): Adjust prototype. + +2025-10-15 Tobias Burnus <tburnus@baylibre.com> + + * config/gcn/gcn-devices.def (gfx942, gfx950): Set generic name + to GFX9_4_GENERIC. + * config/gcn/t-omp-device: Include generic names for OpenMP's + ISA trait. + +2025-10-15 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + * print-tree.cc (print_node): Print out clique/base + for MEM_REF and TARGET_MEM_REF. + +2025-10-15 Richard Earnshaw <rearnsha@arm.com> + + PR target/118460 + * config/arm/arm.cc (arm_canonicalize_comparison): For floating- + point comparisons, swap the operand order if that will be more + likely to produce a comparison that can be used with VSEL. + (arm_validize_comparison): Make sure that HFmode comparisons + are compatible with VSEL. + +2025-10-15 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122037 + * tree-ssa-dce.cc (eliminate_unnecessary_stmts): Remove + __builtin_stack_save when the lhs is unused. + +2025-10-15 Alice Carlotti <alice.carlotti@arm.com> + + * config/aarch64/aarch64-sys-regs.def: Copy from Binutils. + * config/aarch64/aarch64.cc (F_ARCHEXT): Delete flag. + * config/aarch64/aarch64.h + (AARCH64_FL_AMU): Delete unused macro. + (AARCH64_FL_SCXTNUM): Ditto. + (AARCH64_FL_ID_PFR2): Ditto. + (AARCH64_FL_AIE): Ditto. + (AARCH64_FL_DEBUGv8p9): Ditto. + (AARCH64_FL_FGT2): Ditto. + (AARCH64_FL_PFAR): Ditto. + (AARCH64_FL_PMUv3_ICNTR): Ditto. + (AARCH64_FL_PMUv3_SS): Ditto. + (AARCH64_FL_PMUv3p9): Ditto. + (AARCH64_FL_S1PIE): Ditto. + (AARCH64_FL_S1POE): Ditto. + (AARCH64_FL_S2PIE): Ditto. + (AARCH64_FL_S2POE): Ditto. + (AARCH64_FL_SCTLR2): Ditto. + (AARCH64_FL_SEBEP): Ditto. + (AARCH64_FL_SPE_FDS): Ditto. + (AARCH64_FL_TCR2): Ditto. + +2025-10-15 Sebastian Pop <spop@nvidia.com> + + * doc/invoke.texi (ftree-parallelize-loops): Update. + * common.opt (ftree-parallelize-loops): Add alias that maps to + special value INT_MAX for runtime thread detection. + * tree-parloops.cc (create_parallel_loop): Use INT_MAX for runtime + detection. Call gimple_build_omp_parallel without building a + OMP_CLAUSE_NUM_THREADS clause. + (gen_parallel_loop): For auto-detection, use a conservative + estimate of 2 threads. + (parallelize_loops): Same. + +2025-10-15 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/122189 + * config/arm/iterators.md (VxCIQ_carry, VxCIQ_M_carry, VxCQ_carry) + (VxCQ_M_carry): New iterators. + * config/arm/mve.md (get_fpscr_nzcvqc, set_fpscr_nzcvqc): Use + unspec instead of unspec_volatile. + (vadciq, vadciq_m, vadcq, vadcq_m): Use vfpcc in operation. Use a + different unspec code for carry calcultation. + * config/arm/unspecs.md (VADCQ_U_carry, VADCQ_M_U_carry) + (VADCQ_S_carry, VADCQ_M_S_carry, VSBCIQ_U_carry ,VSBCIQ_S_carry + ,VSBCIQ_M_U_carry ,VSBCIQ_M_S_carry ,VSBCQ_U_carry ,VSBCQ_S_carry + ,VSBCQ_M_U_carry ,VSBCQ_M_S_carry ,VADCIQ_U_carry + ,VADCIQ_M_U_carry ,VADCIQ_S_carry ,VADCIQ_M_S_carry): New unspec + codes. + +2025-10-15 Roger Sayle <roger@nextmovesoftware.com> + + PR rtl-optimization/122266 + * combine.cc (struct reg_stat_type): Change types of sign_bit_copies + and last_set_sign_bit_copies to unsigned short, to avoid overflows + on TImode (and wider) values. + +2025-10-15 Jan Hubicka <hubicka@ucw.cz> + + * auto-profile.cc (scale_bb_profile): Use + profile_count::max_prefer_initialized. + (afdo_adjust_guessed_profile): Likewise. + * bb-reorder.cc (edge_order): Do not use max. + * cfghooks.cc (merge_blocks): Likewise. + * ipa-fnsummary.cc (param_change_prob): Likewise. + * ipa-inline-transform.cc (inline_transform): Likewise. + * predict.cc (update_max_bb_count): Likewise. + (estimate_bb_frequencies): Likewise. + (rebuild_frequencies): Likewise. + * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Likewise. + * profile-count.h (profile_count::max): Rename to + (profile_count::max_prefer_initialized): this; update handling + of qualities. + +2025-10-15 Haochen Jiang <haochen.jiang@intel.com> + + * common/config/i386/cpuinfo.h + (get_intel_cpu): Handle Wildcat Lake. + * common/config/i386/i386-common.cc (processor_name): + Add Wildcat Lake. + * doc/invoke.texi: Ditto. + +2025-10-15 Haochen Jiang <haochen.jiang@intel.com> + + * config/i386/i386.h + (PTA_PANTHERLAKE): Remove PREFETCHI. + (PTA_DIAMONDRAPIDS): Remove USER_MSR. + * doc/invoke.texi: Correct documentation. + +2025-10-15 Pan Li <pan2.li@intel.com> + + * config/riscv/autovec-opt.md: Take concrete op instead + of any_widen_binop for vwaddu/vwsubu wx combine. + 2025-10-14 Richard Biener <rguenther@suse.de> * tree-vectorizer.h (REDUC_GROUP_FIRST_ELEMENT, diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 0535efa..9456ec9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20251015 +20251017 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index cf1408d..8d9528c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1861,6 +1861,8 @@ OBJS = \ # Objects in libcommon.a, potentially used by all host binaries and with # no target dependencies. OBJS-libcommon = \ + custom-sarif-properties/digraphs.o \ + custom-sarif-properties/state-graphs.o \ diagnostic-global-context.o \ diagnostics/buffering.o \ diagnostics/changes.o \ @@ -1880,7 +1882,6 @@ OBJS-libcommon = \ diagnostics/paths.o \ diagnostics/paths-output.o \ diagnostics/source-printing.o \ - diagnostics/state-graphs.o \ diagnostics/state-graphs-to-dot.o \ diagnostics/selftest-context.o \ diagnostics/selftest-logical-locations.o \ 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); } } diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 9e7edbb..c83eace 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -281,4 +281,6 @@ #undef SUBTARGET_DRIVER_SELF_SPECS #define SUBTARGET_DRIVER_SELF_SPECS \ "%{m64:-maix64} %<m64", \ -"%{m32:-maix32} %<m32" +"%{m32:-maix32} %<m32", \ +"%{fstack-protector*: %<fstack-protector* \ + %estack-protector not supported on AIX}" diff --git a/gcc/configure b/gcc/configure index 485219b..962511f 100755 --- a/gcc/configure +++ b/gcc/configure @@ -36891,7 +36891,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} "depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;; "gccdepdir":C) ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR - for lang in $subdirs c-family common analyzer diagnostics text-art rtl-ssa sym-exec + for lang in $subdirs c-family common analyzer custom-sarif-properties diagnostics text-art rtl-ssa sym-exec do ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR done ;; diff --git a/gcc/configure.ac b/gcc/configure.ac index 04f86b5..1e5f7c3 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1368,7 +1368,7 @@ AC_CHECK_HEADERS(ext/hash_map) ZW_CREATE_DEPDIR AC_CONFIG_COMMANDS([gccdepdir],[ ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR - for lang in $subdirs c-family common analyzer diagnostics text-art rtl-ssa sym-exec + for lang in $subdirs c-family common analyzer custom-sarif-properties diagnostics text-art rtl-ssa sym-exec do ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR done], [subdirs="$subdirs" ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR]) diff --git a/gcc/custom-sarif-properties/digraphs.cc b/gcc/custom-sarif-properties/digraphs.cc new file mode 100644 index 0000000..30ca2b6 --- /dev/null +++ b/gcc/custom-sarif-properties/digraphs.cc @@ -0,0 +1,28 @@ +/* Extra properties for digraphs in SARIF property bags. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +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 +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "json.h" +#include "custom-sarif-properties/digraphs.h" + +const json::string_property custom_sarif_properties::digraphs::digraph::kind + ("gcc/digraphs/graph/kind"); diff --git a/gcc/custom-sarif-properties/digraphs.h b/gcc/custom-sarif-properties/digraphs.h new file mode 100644 index 0000000..93817ed --- /dev/null +++ b/gcc/custom-sarif-properties/digraphs.h @@ -0,0 +1,37 @@ +/* Extra properties for digraphs in SARIF property bags. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +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 +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_CUSTOM_SARIF_PROPERTIES_DIGRAPHS_H +#define GCC_CUSTOM_SARIF_PROPERTIES_DIGRAPHS_H + +/* SARIF property names relating to digraphs. */ + +namespace custom_sarif_properties { + namespace digraphs { + namespace digraph { + /* A hint about the kind of graph we have, + and thus what kinds of nodes and edges to expect. */ + extern const json::string_property kind; + // string; values: "cfg" + } + } +} + +#endif /* ! GCC_CUSTOM_SARIF_PROPERTIES_DIGRAPHS_H */ diff --git a/gcc/custom-sarif-properties/state-graphs.cc b/gcc/custom-sarif-properties/state-graphs.cc new file mode 100644 index 0000000..cc56138 --- /dev/null +++ b/gcc/custom-sarif-properties/state-graphs.cc @@ -0,0 +1,161 @@ +/* Properties for capturing state graphs in SARIF property bags. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +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 +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "json.h" +#include "custom-sarif-properties/state-graphs.h" + +/* graph. */ +namespace graph = custom_sarif_properties::state_graphs::graph; +#define STATE_GRAPH_PREFIX "gcc/diagnostic_state_graph/" +const char *const graph::prefix = STATE_GRAPH_PREFIX; +#undef STATE_GRAPH_PREFIX + +/* node. */ +namespace node = custom_sarif_properties::state_graphs::node; +#define STATE_NODE_PREFIX "gcc/diagnostic_state_node/" + +const json::enum_property<enum node::kind_t> + node::kind_prop (STATE_NODE_PREFIX "kind"); + +const json::string_property node::function (STATE_NODE_PREFIX "function"); + +const json::string_property node::dynamic_extents + (STATE_NODE_PREFIX "dynamic-extents"); + +const json::string_property node::name (STATE_NODE_PREFIX "name"); +const json::string_property node::type (STATE_NODE_PREFIX "type"); +const json::json_property node::value (STATE_NODE_PREFIX "value"); +const json::string_property node::value_str (STATE_NODE_PREFIX "value_str"); + +const json::string_property node::index (STATE_NODE_PREFIX "index"); + +const json::string_property node::bits (STATE_NODE_PREFIX "bits"); + +const json::string_property node::num_bits (STATE_NODE_PREFIX "num_bits"); + +const json::string_property node::deallocator (STATE_NODE_PREFIX "deallocator"); + +const json::string_property node::expected_deallocators + (STATE_NODE_PREFIX "expected-deallocators"); + +const json::enum_property<enum node::dynalloc_state_t> + node::dynalloc_state_prop (STATE_NODE_PREFIX "dynalloc-state"); + +#undef STATE_NODE_PREFIX + + +/* edge. */ +namespace edge_props = custom_sarif_properties::state_graphs::edge; +#define STATE_EDGE_PREFIX "gcc/diagnostic_state_edge/" +extern const char *const edge_props::prefix = STATE_EDGE_PREFIX; +#undef STATE_EDGE_PREFIX + +// Traits for enum node:kind_t + +namespace json { + +template<> +enum node::kind_t +json::enum_traits<enum node::kind_t>::get_unknown_value () +{ + return node::kind_t::other; +} + +static const char * const node_kind_strs[] = { + "globals", + "code", + "function", + "stack", + "stack-frame", + "heap", + "thread-local", + "dynalloc-buffer", + "variable", + "field", + "padding", + "element", + "other", +}; + +template<> +bool +json::enum_traits<enum node::kind_t>:: +maybe_get_value_from_string (const char *str, + enum_t &out) +{ + for (size_t i = 0; i < ARRAY_SIZE (node_kind_strs); ++i) + if (!strcmp (node_kind_strs[i], str)) + { + out = static_cast<enum_t> (i); + return true; + } + return false; +} + +template<> +const char * +json::enum_traits<enum node::kind_t>::get_string_for_value (enum_t value) +{ + return node_kind_strs[static_cast<int> (value)]; +} + +// Traits for enum node:dynalloc_state_t + +template<> +enum node::dynalloc_state_t +json::enum_traits<enum node::dynalloc_state_t>::get_unknown_value () +{ + return node::dynalloc_state_t::unknown; +} + +static const char * const dynalloc_state_strs[] = { + "unknown", + "nonnull", + "unchecked", + "freed" +}; + +template<> +bool +json::enum_traits<enum node::dynalloc_state_t>:: +maybe_get_value_from_string (const char *str, + enum_t &out) +{ + for (size_t i = 0; i < ARRAY_SIZE (dynalloc_state_strs); ++i) + if (!strcmp (dynalloc_state_strs[i], str)) + { + out = static_cast<enum_t> (i); + return true; + } + return false; +} + +template<> +const char * +json::enum_traits<enum node::dynalloc_state_t>:: +get_string_for_value (enum_t value) +{ + return dynalloc_state_strs[static_cast <size_t> (value)]; +} + +} // namespace json diff --git a/gcc/custom-sarif-properties/state-graphs.h b/gcc/custom-sarif-properties/state-graphs.h new file mode 100644 index 0000000..aa18d6a --- /dev/null +++ b/gcc/custom-sarif-properties/state-graphs.h @@ -0,0 +1,98 @@ +/* Properties for capturing state graphs in SARIF property bags. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +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 +<http://www.gnu.org/licenses/>. */ + +#include "json.h" + +#ifndef GCC_DIAGNOSTICS_SARIF_PROPERTIES_STATE_GRAPHS_H +#define GCC_DIAGNOSTICS_SARIF_PROPERTIES_STATE_GRAPHS_H + +/* SARIF property names relating to GCC's CFGs. */ + +namespace custom_sarif_properties { + namespace state_graphs { + namespace graph { + extern const char *const prefix; + } + namespace node { + + enum class kind_t + { + // 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 + }; + + enum class dynalloc_state_t + { + unknown, + nonnull, + unchecked, + freed + }; + + extern const json::enum_property<enum kind_t> kind_prop; + + extern const json::string_property function; + extern const json::string_property dynamic_extents; + extern const json::string_property name; + extern const json::string_property type; + /* The value of a memory region, expressed as a json::value. */ + extern const json::json_property value; + /* The value of a memory region, expressed as a string. */ + extern const json::string_property value_str; + + /* For element nodes, the index within the array. */ + extern const json::string_property index; + + /* The range of bits or bytes within the base region. */ + extern const json::string_property bits; + + /* The size of a padding region. */ + extern const json::string_property num_bits; + + extern const json::string_property deallocator; + extern const json::string_property expected_deallocators; + extern const json::enum_property<enum dynalloc_state_t> + dynalloc_state_prop; + } + namespace edge { + extern const char *const prefix; + } + } +} + +#endif /* ! GCC_DIAGNOSTICS_SARIF_PROPERTIES_STATE_GRAPHS_H */ diff --git a/gcc/diagnostics/diagnostics-selftests.cc b/gcc/diagnostics/diagnostics-selftests.cc index 94a212a..757655b 100644 --- a/gcc/diagnostics/diagnostics-selftests.cc +++ b/gcc/diagnostics/diagnostics-selftests.cc @@ -46,7 +46,6 @@ run_diagnostics_selftests () sarif_sink_cc_tests (); digraphs_cc_tests (); output_spec_cc_tests (); - state_graphs_cc_tests (); lazy_paths_cc_tests (); paths_output_cc_tests (); changes_cc_tests (); diff --git a/gcc/diagnostics/diagnostics-selftests.h b/gcc/diagnostics/diagnostics-selftests.h index 994ebad..5a68a04 100644 --- a/gcc/diagnostics/diagnostics-selftests.h +++ b/gcc/diagnostics/diagnostics-selftests.h @@ -44,7 +44,6 @@ extern void paths_output_cc_tests (); extern void sarif_sink_cc_tests (); extern void selftest_logical_locations_cc_tests (); extern void source_printing_cc_tests (); -extern void state_graphs_cc_tests (); } /* end of namespace diagnostics::selftest. */ diff --git a/gcc/diagnostics/digraphs.cc b/gcc/diagnostics/digraphs.cc index 4a2ea4f..59a9af0 100644 --- a/gcc/diagnostics/digraphs.cc +++ b/gcc/diagnostics/digraphs.cc @@ -30,13 +30,15 @@ along with GCC; see the file COPYING3. If not see #include "graphviz.h" #include "diagnostics/digraphs.h" #include "diagnostics/sarif-sink.h" +#include "custom-sarif-properties/digraphs.h" -#include "selftest.h" - +using digraph_object = diagnostics::digraphs::object; using digraph = diagnostics::digraphs::digraph; using digraph_node = diagnostics::digraphs::node; using digraph_edge = diagnostics::digraphs::edge; +namespace properties = custom_sarif_properties::digraphs; + namespace { class conversion_to_dot @@ -171,66 +173,145 @@ conversion_to_dot::has_edges_p (const digraph_node &input_node) // class object +/* String properties. */ + const char * -diagnostics::digraphs::object:: -get_attr (const char *key_prefix, const char *key) const +digraph_object::get_property (const json::string_property &property) const { if (!m_property_bag) return nullptr; - std::string prefixed_key = std::string (key_prefix) + key; - if (json::value *jv = m_property_bag->get (prefixed_key.c_str ())) + if (json::value *jv = m_property_bag->get (property.m_key.get ())) if (json::string *jstr = jv->dyn_cast_string ()) return jstr->get_string (); return nullptr; } void -diagnostics::digraphs::object:: -set_attr (const char *key_prefix, const char *key, const char *value) +digraph_object::set_property (const json::string_property &property, + const char *utf8_value) +{ + auto &bag = ensure_property_bag (); + bag.set_string (property.m_key.get (), utf8_value); +} + +/* Integer properties. */ + +bool +digraph_object::maybe_get_property (const json::integer_property &property, + long &out_value) const +{ + if (!m_property_bag) + return false; + if (json::value *jv = m_property_bag->get (property.m_key.get ())) + if (json::integer_number *jnum = jv->dyn_cast_integer_number ()) + { + out_value = jnum->get (); + return true; + } + return false; +} + +void +digraph_object::set_property (const json::integer_property &property, long value) +{ + auto &bag = ensure_property_bag (); + bag.set_integer (property.m_key.get (), value); +} + +/* Bool properties. */ +void +digraph_object::set_property (const json::bool_property &property, bool value) +{ + auto &bag = ensure_property_bag (); + bag.set_bool (property.m_key.get (), value); +} + +tristate +digraph_object:: +get_property_as_tristate (const json::bool_property &property) const +{ + if (m_property_bag) + { + if (json::value *jv = m_property_bag->get (property.m_key.get ())) + switch (jv->get_kind ()) + { + default: + break; + case json::JSON_TRUE: + return tristate (true); + case json::JSON_FALSE: + return tristate (false); + } + } + return tristate::unknown (); +} + +/* Array-of-string properties. */ +json::array * +digraph_object::get_property (const json::array_of_string_property &property) const { - set_json_attr (key_prefix, key, std::make_unique<json::string> (value)); + if (m_property_bag) + if (json::value *jv = m_property_bag->get (property.m_key.get ())) + if (json::array *arr = jv->dyn_cast_array ()) + return arr; + return nullptr; +} + +/* json::value properties. */ +const json::value * +digraph_object::get_property (const json::json_property &property) const +{ + if (m_property_bag) + return m_property_bag->get (property.m_key.get ()); + return nullptr; } void -diagnostics::digraphs::object:: -set_json_attr (const char *key_prefix, const char *key, std::unique_ptr<json::value> value) +digraph_object::set_property (const json::json_property &property, + std::unique_ptr<json::value> value) +{ + auto &bag = ensure_property_bag (); + bag.set (property.m_key.get (), std::move (value)); +} + +json::object & +digraph_object::ensure_property_bag () { - std::string prefixed_key = std::string (key_prefix) + key; if (!m_property_bag) - m_property_bag = std::make_unique<json::object> (); - m_property_bag->set (prefixed_key.c_str (), std::move (value)); + m_property_bag = std::make_unique<sarif_property_bag> ( ); + return *m_property_bag; } // class digraph DEBUG_FUNCTION void -diagnostics::digraphs::digraph::dump () const +digraph::dump () const { make_json_sarif_graph ()->dump (); } std::unique_ptr<json::object> -diagnostics::digraphs::digraph::make_json_sarif_graph () const +digraph::make_json_sarif_graph () const { return make_sarif_graph (*this, nullptr, nullptr); } std::unique_ptr<dot::graph> -diagnostics::digraphs::digraph::make_dot_graph () const +digraph::make_dot_graph () const { - conversion_to_dot to_dot; - return to_dot.make_dot_graph_from_diagnostic_graph (*this); + conversion_to_dot converter; + return converter.make_dot_graph_from_diagnostic_graph (*this); } -std::unique_ptr<diagnostics::digraphs::digraph> -diagnostics::digraphs::digraph::clone () const +std::unique_ptr<digraph> +digraph::clone () const { auto result = std::make_unique<diagnostics::digraphs::digraph> (); if (get_property_bag ()) result->set_property_bag (get_property_bag ()->clone_as_object ()); - std::map<diagnostics::digraphs::node *, diagnostics::digraphs::node *> node_mapping; + std::map<digraph_node *, digraph_node *> node_mapping; for (auto &iter : m_nodes) result->add_node (iter->clone (*result, node_mapping)); @@ -241,10 +322,10 @@ diagnostics::digraphs::digraph::clone () const } void -diagnostics::digraphs::digraph::add_edge (const char *id, - node &src_node, - node &dst_node, - const char *label) +digraph::add_edge (const char *id, + node &src_node, + node &dst_node, + const char *label) { auto e = std::make_unique<digraph_edge> (*this, id, @@ -263,7 +344,7 @@ diagnostics::digraphs::digraph::add_edge (const char *id, to edges by id (SARIF 2.1.0's §3.43.2 edgeId property). */ std::string -diagnostics::digraphs::digraph::make_edge_id (const char *edge_id) +digraph::make_edge_id (const char *edge_id) { /* If we have an id, use it. */ if (edge_id) @@ -284,27 +365,38 @@ diagnostics::digraphs::digraph::make_edge_id (const char *edge_id) } } +const char * +digraph::get_graph_kind () const +{ + return get_property (properties::digraph::kind); +} + +void +digraph::set_graph_kind (const char *kind) +{ + set_property (properties::digraph::kind, kind); +} + // class node DEBUG_FUNCTION void -diagnostics::digraphs::node::dump () const +digraph_node::dump () const { to_json_sarif_node ()->dump (); } std::unique_ptr<json::object> -diagnostics::digraphs::node::to_json_sarif_node () const +digraph_node::to_json_sarif_node () const { return make_sarif_node (*this, nullptr, nullptr); } -std::unique_ptr<diagnostics::digraphs::node> -diagnostics::digraphs::node::clone (digraph &new_graph, - std::map<node *, node *> &node_mapping) const +std::unique_ptr<digraph_node> +digraph_node::clone (digraph &new_graph, + std::map<node *, node *> &node_mapping) const { auto result - = std::make_unique<diagnostics::digraphs::node> (new_graph, - get_id ()); + = std::make_unique<digraph_node> (new_graph, get_id ()); node_mapping.insert ({const_cast <node *> (this), result.get ()}); result->set_logical_loc (m_logical_loc); @@ -353,6 +445,9 @@ diagnostics::digraphs::edge::to_json_sarif_edge () const #if CHECKING_P +#include "selftest.h" +#include "custom-sarif-properties/state-graphs.h" + namespace diagnostics { namespace selftest { @@ -391,16 +486,17 @@ test_simple_graph () #define KEY_PREFIX "/placeholder/" auto g = std::make_unique<digraph> (); g->set_description ("test graph"); - g->set_attr (KEY_PREFIX, "date", "1066"); + g->set_property (json::string_property (KEY_PREFIX, "date"), "1066"); auto a = std::make_unique<digraph_node> (*g, "a"); auto b = std::make_unique<digraph_node> (*g, "b"); - b->set_attr (KEY_PREFIX, "color", "red"); + b->set_property (json::string_property (KEY_PREFIX, "color"), "red"); auto c = std::make_unique<digraph_node> (*g, "c"); c->set_label ("I am a node label"); auto e = std::make_unique<digraph_edge> (*g, nullptr, *a, *c); - e->set_attr (KEY_PREFIX, "status", "copacetic"); + e->set_property (json::string_property (KEY_PREFIX, "status"), + "copacetic"); e->set_label ("I am an edge label"); g->add_edge (std::move (e)); @@ -449,6 +545,34 @@ test_simple_graph () } } +static void +test_property_objects () +{ + namespace state_node_properties = custom_sarif_properties::state_graphs::node; + + digraph g; + digraph_node node (g, "a"); + + ASSERT_EQ (node.get_property (state_node_properties::kind_prop), + state_node_properties::kind_t::other); + node.set_property (state_node_properties::kind_prop, + state_node_properties::kind_t::stack); + ASSERT_EQ (node.get_property (state_node_properties::kind_prop), + state_node_properties::kind_t::stack); + + ASSERT_EQ (node.get_property (state_node_properties::dynalloc_state_prop), + state_node_properties::dynalloc_state_t::unknown); + node.set_property (state_node_properties::dynalloc_state_prop, + state_node_properties::dynalloc_state_t::freed); + ASSERT_EQ (node.get_property (state_node_properties::dynalloc_state_prop), + state_node_properties::dynalloc_state_t::freed); + + ASSERT_EQ (node.get_property (state_node_properties::type), nullptr); + node.set_property (state_node_properties::type, "const char *"); + ASSERT_STREQ (node.get_property (state_node_properties::type), + "const char *"); +} + /* Run all of the selftests within this file. */ void @@ -456,6 +580,7 @@ digraphs_cc_tests () { test_empty_graph (); test_simple_graph (); + test_property_objects (); } } // namespace diagnostics::selftest diff --git a/gcc/diagnostics/digraphs.h b/gcc/diagnostics/digraphs.h index 7193ee4..485a189 100644 --- a/gcc/diagnostics/digraphs.h +++ b/gcc/diagnostics/digraphs.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_DIAGNOSTICS_DIGRAPHS_H #include "json.h" +#include "tristate.h" #include "diagnostics/logical-locations.h" class graphviz_out; @@ -55,23 +56,57 @@ class edge; class object { public: - const char * - get_attr (const char *key_prefix, - const char *key) const; - + /* String properties. */ + const char *get_property (const json::string_property &property) const; + void set_property (const json::string_property &property, + const char *utf8_value); + + /* Integer properties. */ + bool maybe_get_property (const json::integer_property &property, long &out) const; + void set_property (const json::integer_property &property, long value); + + /* Bool properties. */ + tristate + get_property_as_tristate (const json::bool_property &property) const; + void set_property (const json::bool_property &property, bool value); + + /* Array-of-string properties. */ + json::array * + get_property (const json::array_of_string_property &property) const; + + /* enum properties. */ + template <typename EnumType> + EnumType + get_property (const json::enum_property<EnumType> &property) const + { + if (m_property_bag) + { + EnumType result; + if (m_property_bag->maybe_get_enum<EnumType> (property, result)) + return result; + } + return json::enum_traits<EnumType>::get_unknown_value (); + } + template <typename EnumType> void - set_attr (const char *key_prefix, - const char *key, - const char *value); + set_property (const json::enum_property<EnumType> &property, + EnumType value) + { + auto &bag = ensure_property_bag (); + bag.set_enum<EnumType> (property, value); + } - void - set_json_attr (const char *key_prefix, - const char *key, - std::unique_ptr<json::value> value); + /* json::value properties. */ + const json::value *get_property (const json::json_property &property) const; + void set_property (const json::json_property &property, + std::unique_ptr<json::value> value); json::object * get_property_bag () const { return m_property_bag.get (); } + json::object & + ensure_property_bag (); + void set_property_bag (std::unique_ptr<json::object> property_bag) { @@ -188,6 +223,9 @@ class digraph : public object std::unique_ptr<digraph> clone () const; + const char *get_graph_kind () const; + void set_graph_kind (const char *); + private: void add_node_id (std::string node_id, node &new_node) @@ -300,7 +338,7 @@ class node : public object clone (digraph &new_graph, std::map<node *, node *> &node_mapping) const; - private: +private: std::string m_id; std::unique_ptr<std::string> m_label; std::vector<std::unique_ptr<node>> m_children; diff --git a/gcc/diagnostics/html-sink.cc b/gcc/diagnostics/html-sink.cc index d3fb107..99d3b9d 100644 --- a/gcc/diagnostics/html-sink.cc +++ b/gcc/diagnostics/html-sink.cc @@ -57,8 +57,8 @@ html_generation_options::html_generation_options () : m_css (true), m_javascript (true), m_show_state_diagrams (false), - m_show_state_diagrams_sarif (false), - m_show_state_diagrams_dot_src (false) + m_show_graph_sarif (false), + m_show_graph_dot_src (false) { } @@ -68,8 +68,8 @@ html_generation_options::dump (FILE *outfile, int indent) const DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_css); DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_javascript); DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_show_state_diagrams); - DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_show_state_diagrams_sarif); - DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_show_state_diagrams_dot_src); + DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_show_graph_sarif); + DIAGNOSTICS_DUMPING_EMIT_BOOL_FIELD (m_show_graph_dot_src); } class html_builder; @@ -640,7 +640,7 @@ html_builder::maybe_make_state_diagram (const paths::event &event) the debug version. */ auto state_graph = event.maybe_make_diagnostic_state_graph - (m_html_gen_opts.m_show_state_diagrams_sarif); + (m_html_gen_opts.m_show_graph_sarif); if (!state_graph) return nullptr; @@ -652,7 +652,7 @@ html_builder::maybe_make_state_diagram (const paths::event &event) auto wrapper = std::make_unique<xml::element> ("div", false); xml::printer xp (*wrapper); - if (m_html_gen_opts.m_show_state_diagrams_sarif) + if (m_html_gen_opts.m_show_graph_sarif) { // For debugging, show the SARIF src inline: pretty_printer pp; @@ -660,7 +660,7 @@ html_builder::maybe_make_state_diagram (const paths::event &event) print_pre_source (xp, pp_formatted_text (&pp)); } - if (m_html_gen_opts.m_show_state_diagrams_dot_src) + if (m_html_gen_opts.m_show_graph_dot_src) { // For debugging, show the dot src inline: pretty_printer pp; @@ -1278,21 +1278,41 @@ void html_builder::add_graph (const digraphs::digraph &dg, xml::element &parent_element) { + auto div = std::make_unique<xml::element> ("div", false); + div->set_attr ("class", "gcc-directed-graph"); + xml::printer xp (*div); + + if (m_html_gen_opts.m_show_graph_sarif) + { + // For debugging, show the SARIF src inline: + pretty_printer pp; + dg.make_json_sarif_graph ()->print (&pp, true); + print_pre_source (xp, pp_formatted_text (&pp)); + } + if (auto dot_graph = dg.make_dot_graph ()) - if (auto svg_element = dot::make_svg_from_graph (*dot_graph)) - { - auto div = std::make_unique<xml::element> ("div", false); - div->set_attr ("class", "gcc-directed-graph"); - xml::printer xp (*div); - if (const char *description = dg.get_description ()) - { - xp.push_tag ("h2", true); - xp.add_text (description); - xp.pop_tag ("h2"); - } - xp.append (std::move (svg_element)); - parent_element.add_child (std::move (div)); - } + { + if (m_html_gen_opts.m_show_graph_dot_src) + { + // For debugging, show the dot src inline: + pretty_printer pp; + dot::writer w (pp); + dot_graph->print (w); + print_pre_source (xp, pp_formatted_text (&pp)); + } + + if (auto svg_element = dot::make_svg_from_graph (*dot_graph)) + { + if (const char *description = dg.get_description ()) + { + xp.push_tag ("h2", true); + xp.add_text (description); + xp.pop_tag ("h2"); + } + xp.append (std::move (svg_element)); + parent_element.add_child (std::move (div)); + } + } } void diff --git a/gcc/diagnostics/html-sink.h b/gcc/diagnostics/html-sink.h index d25ceea..ad68e6f 100644 --- a/gcc/diagnostics/html-sink.h +++ b/gcc/diagnostics/html-sink.h @@ -40,11 +40,12 @@ struct html_generation_options // If true, attempt to show state diagrams at events bool m_show_state_diagrams; - // If true, show the SARIF form of the state with such diagrams - bool m_show_state_diagrams_sarif; + /* If true, show the SARIF form of the state with such diagrams, + and of other graphs. */ + bool m_show_graph_sarif; - // If true, show the .dot source used for the diagram - bool m_show_state_diagrams_dot_src; + // If true, show the .dot source used for such graphs + bool m_show_graph_dot_src; }; extern diagnostics::output_file diff --git a/gcc/diagnostics/output-spec.cc b/gcc/diagnostics/output-spec.cc index dfde7f0..f7cce0a 100644 --- a/gcc/diagnostics/output-spec.cc +++ b/gcc/diagnostics/output-spec.cc @@ -650,12 +650,12 @@ html_scheme_handler::maybe_handle_kv (const context &ctxt, if (key == "show-state-diagrams") return parse_bool_value (ctxt, key, value, m_html_gen_opts.m_show_state_diagrams); - if (key == "show-state-diagrams-dot-src") + if (key == "show-graph-dot-src") return parse_bool_value (ctxt, key, value, - m_html_gen_opts.m_show_state_diagrams_dot_src); - if (key == "show-state-diagrams-sarif") + m_html_gen_opts.m_show_graph_dot_src); + if (key == "show-graph-sarif") return parse_bool_value (ctxt, key, value, - m_html_gen_opts.m_show_state_diagrams_sarif); + m_html_gen_opts.m_show_graph_sarif); return result::unrecognized; } @@ -666,8 +666,8 @@ html_scheme_handler::get_keys (auto_vec<const char *> &out) const out.safe_push ("file"); out.safe_push ("javascript"); out.safe_push ("show-state-diagrams"); - out.safe_push ("show-state-diagrams-dot-src"); - out.safe_push ("show-state-diagrams-sarif"); + out.safe_push ("show-graph-dot-src"); + out.safe_push ("show-graph-sarif"); } } // namespace output_spec diff --git a/gcc/diagnostics/state-graphs-to-dot.cc b/gcc/diagnostics/state-graphs-to-dot.cc index 2d80e6b..790576c 100644 --- a/gcc/diagnostics/state-graphs-to-dot.cc +++ b/gcc/diagnostics/state-graphs-to-dot.cc @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" +#include "custom-sarif-properties/state-graphs.h" #include "diagnostics/state-graphs.h" #include "graphviz.h" #include "xml.h" @@ -36,6 +37,8 @@ along with GCC; see the file COPYING3. If not see using namespace diagnostics; using namespace diagnostics::state_graphs; +namespace state_node_properties = custom_sarif_properties::state_graphs::node; + static int get_depth (const digraphs::node &n) { @@ -47,28 +50,28 @@ get_depth (const digraphs::node &n) } static const char * -get_color_for_dynalloc_state (enum node_dynalloc_state dynalloc_st) +get_color_for_dynalloc_state (enum state_node_properties::dynalloc_state_t dynalloc_st) { switch (dynalloc_st) { default: gcc_unreachable (); break; - case node_dynalloc_state::unknown: - case node_dynalloc_state::nonnull: + case state_node_properties::dynalloc_state_t::unknown: + case state_node_properties::dynalloc_state_t::nonnull: return nullptr; - case node_dynalloc_state::unchecked: + case state_node_properties::dynalloc_state_t::unchecked: return "#ec7a08"; // pf-orange-400 - case node_dynalloc_state::freed: + case state_node_properties::dynalloc_state_t::freed: return "#cc0000"; // pf-red-100 } } static void set_color_for_dynalloc_state (dot::attr_list &attrs, - enum node_dynalloc_state state) + enum state_node_properties::dynalloc_state_t state) { if (const char *color = get_color_for_dynalloc_state (state)) attrs.add (dot::id ("color"), dot::id (color)); @@ -106,7 +109,7 @@ public: = std::make_unique<dot::subgraph> (dot::id ("cluster_memory_regions")); for (size_t i = 0; i < input_state_graph.get_num_nodes (); ++i) on_input_state_node (*root_cluster, - state_node_ref (input_state_graph.get_node (i))); + input_state_graph.get_node (i)); add_stmt (std::move (root_cluster)); /* Now create dot edges for edges in input_stage_graph. */ @@ -126,7 +129,8 @@ public: auto e = std::make_unique<dot::edge_stmt> (src_port_id->second, dst_port_id->second); set_color_for_dynalloc_state - (e->m_attrs, state_node_ref (dst_node).get_dynalloc_state ()); + (e->m_attrs, + dst_node.get_property (state_node_properties::dynalloc_state_prop)); add_stmt (std::move (e)); } @@ -147,9 +151,9 @@ private: } dot::id - make_id (state_node_ref state_node, bool cluster) + make_id (const diagnostics::digraphs::node &state_node, bool cluster) { - std::string input_node_id = state_node.m_node.get_id (); + std::string input_node_id = state_node.get_id (); if (cluster) return std::string ("cluster_") + input_node_id; else @@ -157,44 +161,44 @@ private: } bool - starts_node_p (state_node_ref state_node) + starts_node_p (const diagnostics::digraphs::node &state_node) { - switch (state_node.get_node_kind ()) + switch (state_node.get_property (state_node_properties::kind_prop)) { default: return false; - case node_kind::stack: + case state_node_properties::kind_t::stack: /* We want all frames in the stack in the same table, so they are grouped. */ - case node_kind::dynalloc_buffer: - case node_kind::variable: + case state_node_properties::kind_t::dynalloc_buffer: + case state_node_properties::kind_t::variable: return true; } } const char * - get_label_for_node (state_node_ref state_node) + get_label_for_node (const diagnostics::digraphs::node &state_node) { - switch (state_node.get_node_kind ()) + switch (state_node.get_property (state_node_properties::kind_prop)) { default: return nullptr; - case node_kind::globals: + case state_node_properties::kind_t::globals: return _("Globals"); - case node_kind::code: + case state_node_properties::kind_t::code: return _("Code"); - case node_kind::stack: + case state_node_properties::kind_t::stack: return _("Stack"); - case node_kind::heap_: + case state_node_properties::kind_t::heap_: return _("Heap"); } } void on_input_state_node (dot::subgraph &parent_subgraph, - state_node_ref state_node) + const diagnostics::digraphs::node &state_node) { dot::id sg_id = make_id (state_node, true); @@ -207,7 +211,7 @@ private: xp.set_attr ("cellborder", "1"); xp.set_attr ("cellspacing", "0"); - const int max_depth = get_depth (state_node.m_node); + const int max_depth = get_depth (state_node); const int num_columns = max_depth + 2; dot::id id_of_dot_node = make_id (state_node, false); @@ -233,9 +237,9 @@ private: child_subgraph->add_attr (dot::id ("label"), dot::id (label)); // recurse: - for (size_t i = 0; i < state_node.m_node.get_num_children (); ++i) + for (size_t i = 0; i < state_node.get_num_children (); ++i) on_input_state_node (*child_subgraph, - state_node.m_node.get_child (i)); + state_node.get_child (i)); parent_subgraph.m_stmt_list.add_stmt (std::move (child_subgraph)); } } @@ -246,10 +250,10 @@ private: add_title_tr (const dot::id &id_of_dot_node, xml::printer &xp, int num_columns, - state_node_ref state_node, + const diagnostics::digraphs::node &state_node, std::string heading, enum style styl, - enum node_dynalloc_state dynalloc_state) + enum state_node_properties::dynalloc_state_t dynalloc_state) { xp.push_tag ("tr", true); xp.push_tag ("td", false); @@ -298,48 +302,51 @@ private: void on_node_in_table (const dot::id &id_of_dot_node, xml::printer &xp, - state_node_ref state_node, + const diagnostics::digraphs::node &state_node, int max_depth, int depth, int num_columns) { bool recurse = true; - auto input_node_kind = state_node.get_node_kind (); + auto input_node_kind + = state_node.get_property (state_node_properties::kind_prop); switch (input_node_kind) { - case node_kind::padding: - case node_kind::other: + case state_node_properties::kind_t::padding: + case state_node_properties::kind_t::other: return; - case node_kind::stack: + case state_node_properties::kind_t::stack: add_title_tr (id_of_dot_node, xp, num_columns, state_node, "Stack", style::h1, - node_dynalloc_state::unknown); + state_node_properties::dynalloc_state_t::unknown); break; - case node_kind::stack_frame: + case state_node_properties::kind_t::stack_frame: if (auto logical_loc = state_node.get_logical_loc ()) if (const char *function = m_logical_loc_mgr.get_short_name (logical_loc)) add_title_tr (id_of_dot_node, xp, num_columns, state_node, std::string ("Frame: ") + function, style::h2, - node_dynalloc_state::unknown); + state_node_properties::dynalloc_state_t::unknown); break; - case node_kind::dynalloc_buffer: + case state_node_properties::kind_t::dynalloc_buffer: { - enum node_dynalloc_state dynalloc_st - = state_node.get_dynalloc_state (); - const char *extents = state_node.get_dynamic_extents (); - const char *type = state_node.get_type (); + enum state_node_properties::dynalloc_state_t dynalloc_st + = state_node.get_property + (state_node_properties::dynalloc_state_prop); + const char *extents + = state_node.get_property (state_node_properties::dynamic_extents); + const char *type = state_node.get_property (state_node_properties::type); pretty_printer pp; switch (dynalloc_st) { default: gcc_unreachable (); - case node_dynalloc_state::unknown: - case node_dynalloc_state::nonnull: + case state_node_properties::dynalloc_state_t::unknown: + case state_node_properties::dynalloc_state_t::nonnull: if (type) { if (extents) @@ -356,7 +363,7 @@ private: } break; - case node_dynalloc_state::unchecked: + case state_node_properties::dynalloc_state_t::unchecked: if (type) { if (extents) @@ -371,7 +378,7 @@ private: } break; - case node_dynalloc_state::freed: + case state_node_properties::dynalloc_state_t::freed: // TODO: show deallocator // TODO: show deallocation event pp_printf (&pp, "Freed buffer"); @@ -404,9 +411,10 @@ private: { default: break; - case node_kind::variable: + case state_node_properties::kind_t::variable: { - const char *name = state_node.get_name (); + const char *name + = state_node.get_property (state_node_properties::name); gcc_assert (name); xp.push_tag ("td", false); maybe_add_dst_port (id_of_dot_node, xp, state_node); @@ -416,9 +424,10 @@ private: xp.pop_tag ("td"); } break; - case node_kind::element: + case state_node_properties::kind_t::element: { - const char *index = state_node.get_index (); + const char *index + = state_node.get_property (state_node_properties::index); gcc_assert (index); xp.push_tag ("td", false); maybe_add_dst_port (id_of_dot_node, xp, state_node); @@ -430,9 +439,10 @@ private: xp.pop_tag ("td"); } break; - case node_kind::field: + case state_node_properties::kind_t::field: { - const char *name = state_node.get_name (); + const char *name + = state_node.get_property (state_node_properties::name); gcc_assert (name); xp.push_tag ("td", false); maybe_add_dst_port (id_of_dot_node, xp, state_node); @@ -445,7 +455,8 @@ private: break; } - if (const char *type = state_node.get_type ()) + if (const char *type + = state_node.get_property (state_node_properties::type)) { xp.push_tag ("td", false); xp.set_attr ("align", "right"); @@ -455,7 +466,8 @@ private: xp.pop_tag ("td"); } - if (const char *value = state_node.get_value ()) + if (const char *value + = state_node.get_property (state_node_properties::value_str)) { xp.push_tag ("td", false); xp.set_attr ("align", "left"); @@ -466,15 +478,16 @@ private: xp.pop_tag ("td"); recurse = false; } + xp.pop_tag ("tr"); } break; } if (recurse) - for (size_t i = 0; i < state_node.m_node.get_num_children (); ++i) + for (size_t i = 0; i < state_node.get_num_children (); ++i) on_node_in_table (id_of_dot_node, xp, - state_node.m_node.get_child (i), + state_node.get_child (i), max_depth, depth + 1, num_columns); } @@ -497,9 +510,9 @@ private: void maybe_add_src_port (const dot::id &id_of_dot_node, xml::printer &xp, - state_node_ref state_node) + const diagnostics::digraphs::node &state_node) { - auto iter = m_src_nodes.find (&state_node.m_node); + auto iter = m_src_nodes.find (&state_node); if (iter == m_src_nodes.end ()) return; @@ -507,7 +520,7 @@ private: dot::node_id node_id (id_of_dot_node, dot::port (src_id, dot::compass_pt::e)); - m_src_node_to_port_id.insert ({&state_node.m_node, node_id}); + m_src_node_to_port_id.insert ({&state_node, node_id}); xp.set_attr ("port", src_id.m_str); } @@ -517,9 +530,9 @@ private: void maybe_add_dst_port (const dot::id &id_of_dot_node, xml::printer &xp, - state_node_ref state_node) + const diagnostics::digraphs::node &state_node) { - auto iter = m_dst_nodes.find (&state_node.m_node); + auto iter = m_dst_nodes.find (&state_node); if (iter == m_dst_nodes.end ()) return; @@ -527,7 +540,7 @@ private: dot::node_id node_id (id_of_dot_node, dot::port (dst_id/*, dot::compass_pt::w*/)); - m_dst_node_to_port_id.insert ({&state_node.m_node, node_id}); + m_dst_node_to_port_id.insert ({&state_node, node_id}); xp.set_attr ("port", dst_id.m_str); } @@ -535,11 +548,11 @@ private: const logical_locations::manager &m_logical_loc_mgr; /* All nodes involved in edges (and thus will need a port). */ - std::set<digraphs::node *> m_src_nodes; - std::set<digraphs::node *> m_dst_nodes; + std::set<const digraphs::node *> m_src_nodes; + std::set<const digraphs::node *> m_dst_nodes; - std::map<digraphs::node *, dot::node_id> m_src_node_to_port_id; - std::map<digraphs::node *, dot::node_id> m_dst_node_to_port_id; + std::map<const digraphs::node *, dot::node_id> m_src_node_to_port_id; + std::map<const digraphs::node *, dot::node_id> m_dst_node_to_port_id; }; std::unique_ptr<dot::graph> diff --git a/gcc/diagnostics/state-graphs.cc b/gcc/diagnostics/state-graphs.cc deleted file mode 100644 index 5941c41..0000000 --- a/gcc/diagnostics/state-graphs.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* Extensions to diagnostics::digraphs to support state graphs. - Copyright (C) 2025 Free Software Foundation, Inc. - Contributed by David Malcolm <dmalcolm@redhat.com>. - -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 -<http://www.gnu.org/licenses/>. */ - -#define INCLUDE_ALGORITHM -#define INCLUDE_MAP -#define INCLUDE_SET -#define INCLUDE_STRING -#define INCLUDE_VECTOR -#include "config.h" -#include "system.h" -#include "coretypes.h" - -#include "diagnostics/state-graphs.h" -#include "selftest.h" - -using namespace diagnostics::state_graphs; - -const char * const node_kind_strs[] = { - "globals", - "code", - "function", - "stack", - "stack-frame", - "heap", - "thread-local", - "dynalloc-buffer", - "variable", - "field", - "padding", - "element", - "other", -}; - -const char * -diagnostics::state_graphs::node_kind_to_str (enum node_kind k) -{ - return node_kind_strs[static_cast<int> (k)]; -} - -// struct state_node_ref - -enum node_kind -state_node_ref::get_node_kind () const -{ - const char *value = get_attr ("kind"); - if (!value) - return node_kind::other; - - for (size_t i = 0; i < ARRAY_SIZE (node_kind_strs); ++i) - if (!strcmp (node_kind_strs[i], value)) - return static_cast<enum node_kind> (i); - - return node_kind::other; -} - -void -state_node_ref::set_node_kind (enum node_kind k) -{ - set_attr ("kind", node_kind_to_str (k)); -} - -const char * const dynalloc_state_strs[] = { - "unknown", - "nonnull", - "unchecked", - "freed" -}; - -enum node_dynalloc_state -state_node_ref::get_dynalloc_state () const -{ - const char *value = get_attr ("dynalloc-state"); - if (!value) - return node_dynalloc_state::unknown; - - for (size_t i = 0; i < ARRAY_SIZE (dynalloc_state_strs); ++i) - if (!strcmp (dynalloc_state_strs[i], value)) - return static_cast<enum node_dynalloc_state> (i); - - return node_dynalloc_state::unknown; -} - -void -state_node_ref::set_dynalloc_state (enum node_dynalloc_state s) const -{ - set_attr ("dynalloc-state", - dynalloc_state_strs[static_cast <size_t> (s)]); -} - -const char * -state_node_ref::get_dynamic_extents () const -{ - return m_node.get_attr (STATE_NODE_PREFIX, "dynamic-extents"); -} - -void -state_node_ref::set_json_attr (const char *key, - std::unique_ptr<json::value> value) const -{ - m_node.set_json_attr (STATE_NODE_PREFIX, key, std::move (value)); -} - -#if CHECKING_P - -namespace diagnostics { -namespace selftest { - -static void -test_node_attrs () -{ - digraphs::digraph g; - digraphs::node n (g, "a"); - state_node_ref node_ref (n); - - ASSERT_EQ (node_ref.get_node_kind (), node_kind::other); - node_ref.set_node_kind (node_kind::stack); - ASSERT_EQ (node_ref.get_node_kind (), node_kind::stack); - - ASSERT_EQ (node_ref.get_dynalloc_state (), node_dynalloc_state::unknown); - node_ref.set_dynalloc_state (node_dynalloc_state::freed); - ASSERT_EQ (node_ref.get_dynalloc_state (), node_dynalloc_state::freed); - - ASSERT_EQ (node_ref.get_type (), nullptr); - node_ref.set_type ("const char *"); - ASSERT_STREQ (node_ref.get_type (), "const char *"); -} - -/* Run all of the selftests within this file. */ - -void -state_graphs_cc_tests () -{ - test_node_attrs (); -} - -} // namespace diagnostics::selftest -} // namespace diagnostics - -#endif /* CHECKING_P */ diff --git a/gcc/diagnostics/state-graphs.h b/gcc/diagnostics/state-graphs.h index ad18f82..21aded0 100644 --- a/gcc/diagnostics/state-graphs.h +++ b/gcc/diagnostics/state-graphs.h @@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see #define GCC_DIAGNOSTICS_STATE_GRAPHS_H #include "diagnostics/digraphs.h" -#include "diagnostics/logical-locations.h" /* diagnostics::digraphs provides support for directed graphs. @@ -34,118 +33,11 @@ along with GCC; see the file COPYING3. If not see 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<json::value> value) const; - - diagnostics::digraphs::node &m_node; -}; - extern std::unique_ptr<dot::graph> make_dot_graph (const diagnostics::digraphs::digraph &state_graph, const logical_locations::manager &logical_loc_mgr); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3f53986..9c64acb 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6296,16 +6296,16 @@ These are visible by pressing ``j'' and ``k'' to single-step forward and backward through events. Enabling this option will slow down HTML generation. -@item show-state-diagrams-dot-src=@r{[}yes@r{|}no@r{]} +@item show-graph-dot-src=@r{[}yes@r{|}no@r{]} This is a debugging feature and defaults to @code{no}. -If @code{show-state-diagrams-dot-src=yes} +If @code{show-graph-dot-src=yes} then if @code{show-state-diagrams=yes}, the generated state diagrams will also show the .dot source input to GraphViz used for the diagram. -@item show-state-diagrams-sarif=@r{[}yes@r{|}no@r{]} +@item show-graph-sarif=@r{[}yes@r{|}no@r{]} This is a debugging feature and defaults to @code{no}. -If @code{show-state-diagrams-sarif=yes} +If @code{show-graph-sarif=yes} then if @code{show-state-diagrams=yes}, the generated state diagrams will also show a SARIF representation of the state. diff --git a/gcc/json.cc b/gcc/json.cc index 7153f08..14ff76b 100644 --- a/gcc/json.cc +++ b/gcc/json.cc @@ -394,6 +394,31 @@ object::set_bool (const char *key, bool v) set (key, new json::literal (v)); } +void +object::set_string (const string_property &property, const char *utf8_value) +{ + set_string (property.m_key.get (), utf8_value); +} + +void +object::set_integer (const integer_property &property, long value) +{ + set_integer (property.m_key.get (), value); +} + +void +object::set_bool (const bool_property &property, bool value) +{ + set_bool (property.m_key.get (), value); +} + +void +object::set_array_of_string (const array_of_string_property &property, + std::unique_ptr<json::array> value) +{ + set<array> (property.m_key.get (), std::move (value)); +} + /* Subroutine of json::compare for comparing a pairs of objects. */ int @@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_JSON_H #define GCC_JSON_H +#include "label-text.h" + /* Implementation of JSON, a lightweight data-interchange format. See http://www.json.org/ @@ -116,6 +118,41 @@ struct token } // namespace json::pointer +/* Typesafe way to work with properties in JSON objects. */ + +template <typename Traits> +struct property +{ + explicit property (const char *key) + : m_key (label_text::borrow (key)) + {} + + explicit property (const char *key_prefix, const char *key) + : m_key (label_text::take (concat (key_prefix, key, nullptr))) + {} + + label_text m_key; +}; + +using string_property = property<string>; +using integer_property = property<integer_number>; +using bool_property = property<literal>; +using json_property = property<value>; +using array_of_string_property = property<array>; + +template <typename EnumType> +struct enum_traits +{ + typedef EnumType enum_t; + + static enum_t get_unknown_value (); + static bool maybe_get_value_from_string (const char *, enum_t &out); + static const char *get_string_for_value (enum_t value); +}; + +template <typename EnumType> +using enum_property = property<enum_traits<EnumType>>; + /* Base class of JSON value. */ class value @@ -130,6 +167,8 @@ class value void DEBUG_FUNCTION dump () const; virtual object *dyn_cast_object () { return nullptr; } + virtual array *dyn_cast_array () { return nullptr; } + virtual integer_number *dyn_cast_integer_number () { return nullptr; } virtual string *dyn_cast_string () { return nullptr; } static int compare (const json::value &val_a, const json::value &val_b); @@ -183,6 +222,19 @@ class object : public value /* Set to literal true/false. */ void set_bool (const char *key, bool v); + /* Typesafe access to properties by name (such as from a schema). */ + void set_string (const string_property &property, const char *utf8_value); + void set_integer (const integer_property &property, long value); + void set_bool (const bool_property &property, bool value); + void set_array_of_string (const array_of_string_property &property, + std::unique_ptr<json::array> value); + template <typename EnumType> + bool maybe_get_enum (const enum_property<EnumType> &property, + EnumType &out) const; + template <typename EnumType> + void set_enum (const enum_property<EnumType> &property, + EnumType value); + static int compare (const json::object &obj_a, const json::object &obj_b); size_t get_num_keys () const { return m_keys.length (); } @@ -210,6 +262,8 @@ class array : public value void print (pretty_printer *pp, bool formatted) const final override; std::unique_ptr<value> clone () const final override; + array *dyn_cast_array () final override { return this; } + void append (value *v); void append_string (const char *utf8_value); @@ -269,6 +323,8 @@ class integer_number : public value void print (pretty_printer *pp, bool formatted) const final override; std::unique_ptr<value> clone () const final override; + integer_number *dyn_cast_integer_number () final override { return this; } + long get () const { return m_value; } private: @@ -317,6 +373,32 @@ class literal : public value enum kind m_kind; }; + +template <typename EnumType> +inline bool +object::maybe_get_enum (const enum_property<EnumType> &property, + EnumType &out) const +{ + if (value *jv = get (property.m_key.get ())) + if (string *jstr = jv->dyn_cast_string ()) + { + if (enum_traits<EnumType>::maybe_get_value_from_string + (jstr->get_string (), out)) + return true; + } + return false; +} + +template <typename EnumType> +inline void +object::set_enum (const enum_property<EnumType> &property, + EnumType value) +{ + const char *str + = json::enum_traits<EnumType>::get_string_for_value (value); + set_string (property.m_key.get (), str); +} + } // namespace json template <> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca170a1..6964114 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,50 @@ +2025-10-16 David Malcolm <dmalcolm@redhat.com> + + * gcc.dg/plugin/diagnostic_plugin_test_graphs.cc + (report_diag_with_graphs): Port from set_attr to set_property. + +2025-10-15 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/121468 + PR tree-optimization/121206 + PR tree-optimization/122200 + * gcc.dg/pr121468.c: New. + * gcc.dg/pr122200.c: New. + +2025-10-15 Richard Earnshaw <rearnsha@arm.com> + + PR target/118460 + * gcc.target/arm/armv8_2-fp16-move-1.c: Adjust expected output. + * gcc.target/arm/armv8_2-fp16-move-2.c: Likewise. + +2025-10-15 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122037 + * gcc.dg/tree-ssa/vla-1.c: New test. + +2025-10-15 Alice Carlotti <alice.carlotti@arm.com> + + * gcc.target/aarch64/acle/rwsr-armv8p9.c: Fix incorrect encoding. + +2025-10-15 Sebastian Pop <spop@nvidia.com> + + * gcc.dg/autopar/runtime-auto.c: New test. + +2025-10-15 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/122189 + * gcc.target/arm/mve/intrinsics/vadcq-check-carry.c: New test. + * gcc.target/arm/mve/intrinsics/vadcq_m_s32.c: Adjust instructions + order. + * gcc.target/arm/mve/intrinsics/vadcq_m_u32.c: Likewise. + * gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c: Likewise. + * gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c: Likewise. + +2025-10-15 Roger Sayle <roger@nextmovesoftware.com> + + PR rtl-optimization/122266 + * gcc.target/i386/pr122266.c: New test case. + 2025-10-14 Patrick Palka <ppalka@redhat.com> PR c++/122192 diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc index 7398a29..8ba576e 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc @@ -210,9 +210,8 @@ report_diag_with_graphs (location_t loc) g->set_description (desc); auto a = std::make_unique<diagnostic_node> (*g, "a"); auto b = std::make_unique<diagnostic_node> (*g, "b"); -#define KEY_PREFIX "/placeholder-prefix/" - b->set_attr (KEY_PREFIX, "color", "red"); -#undef KEY_PREFIX + const json::string_property color ("/placeholder-prefix/color"); + b->set_property (color, "red"); auto c = std::make_unique<diagnostic_node> (*g, "c"); c->set_label ("I am a node label"); diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 97c1bf0..568353a 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7752,7 +7752,9 @@ vect_transform_reduction (loop_vec_info loop_vinfo, assumption is not true: we use reduc_index to record the index of the reduction variable. */ int reduc_index = SLP_TREE_REDUC_IDX (slp_node); - tree vectype_in = SLP_TREE_VECTYPE (SLP_TREE_CHILDREN (slp_node)[0]); + tree vectype_in = SLP_TREE_VECTYPE (slp_node); + if (lane_reducing_op_p (op.code)) + vectype_in = SLP_TREE_VECTYPE (SLP_TREE_CHILDREN (slp_node)[0]); vec_num = vect_get_num_copies (loop_vinfo, SLP_TREE_CHILDREN (slp_node)[0]); diff --git a/include/ChangeLog b/include/ChangeLog index 81faceb..03529c0 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2025-10-16 David Faust <david.faust@oracle.com> + + * dwarf2.def (DW_TAG_GNU_annotation): Add link to wiki page + documenting the extension. + (DW_AT_GNU_annotation): Likewise. + 2025-10-10 Tobias Burnus <tburnus@baylibre.com> * hsa_ext_amd.h (enum hsa_amd_agent_info_s): Add diff --git a/include/dwarf2.def b/include/dwarf2.def index 37b8d6b..6d634d1 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -175,6 +175,8 @@ DW_TAG (DW_TAG_GNU_formal_parameter_pack, 0x4108) DW_TAG (DW_TAG_GNU_call_site, 0x4109) DW_TAG (DW_TAG_GNU_call_site_parameter, 0x410a) +/* GNU annotation extension used by btf_decl_tag and btf_type_tag. + See https://gcc.gnu.org/wiki/GNUAnnotationsDwarf . */ DW_TAG (DW_TAG_GNU_annotation, 0x6001) /* Extensions for UPC. See: http://dwarfstd.org/doc/DWARF4.pdf. */ @@ -459,6 +461,8 @@ DW_AT (DW_AT_GNU_pubtypes, 0x2135) DW_AT (DW_AT_GNU_discriminator, 0x2136) DW_AT (DW_AT_GNU_locviews, 0x2137) DW_AT (DW_AT_GNU_entry_view, 0x2138) +/* GNU annotation extension used by btf_decl_tag and btf_type_tag. + See https://gcc.gnu.org/wiki/GNUAnnotationsDwarf . */ DW_AT (DW_AT_GNU_annotation, 0x2139) /* VMS extensions. */ DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201) diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 8b9f0ff..3414923 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,48 @@ +2025-10-16 Tobias Burnus <tburnus@baylibre.com> + + * testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c: Add + dg-excess-errors to handle possible missing libgomp multi lib. + * testsuite/libgomp.c/declare-variant-4-gfx1030.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx1036.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx11-generic.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx1100.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx1103.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx9-generic.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx900.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx906.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx908.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx90a.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx90c.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx942.c: Likewise. + * testsuite/libgomp.c/declare-variant-4-gfx1031.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1032.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1033.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1034.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1035.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1101.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1102.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1150.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1151.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1152.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx1153.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx902.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx904.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx909.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx950.c: New test. + +2025-10-15 Tobias Burnus <tburnus@baylibre.com> + + * libgomp.texi (OpenMP Context Selectors): Add note that there is + currently an exact match between ISA and compilation, ignoring + compatibilities in both ways. + * testsuite/libgomp.c/declare-variant-4.h: Add missing variant + functions for specific and generic AMD GPUs. + * testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx11-generic.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c: New test. + * testsuite/libgomp.c/declare-variant-4-gfx9-generic.c: New test. + 2025-10-10 Tobias Burnus <tburnus@baylibre.com> * plugin/plugin-gcn.c (is_integrated_apu): New; currently '#if 0'. diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c index 3df81a3..b7b95e6 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c @@ -6,3 +6,20 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx10_3_generic \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available (as this is a generic config), + scan-offload-tree-dump will PASS - but linking fails with the + following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1030.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1030.c index d98d5ef..3703e96 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1030.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1030.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1030 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1031.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1031.c new file mode 100644 index 0000000..e0d6289 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1031.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1031 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1031 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1032.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1032.c new file mode 100644 index 0000000..46174cc2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1032.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1032 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1032 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1033.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1033.c new file mode 100644 index 0000000..1bd6e66 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1033.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1033 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1033 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1034.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1034.c new file mode 100644 index 0000000..4f67a73 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1034.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1034 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1034 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1035.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1035.c new file mode 100644 index 0000000..a69d5e7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1035.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1035 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1035 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c index 93b8641..8c258c4 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1036 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx11-generic.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx11-generic.c index ca03f4a2..fa9efb4 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx11-generic.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx11-generic.c @@ -6,3 +6,20 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx11_generic \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available (as this is a generic config), + scan-offload-tree-dump will PASS - but linking fails with the + following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1100.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1100.c index 6ade352..f0b7c6d 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1100.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1100.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1100 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1101.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1101.c new file mode 100644 index 0000000..213e904 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1101.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1101 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1101 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1102.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1102.c new file mode 100644 index 0000000..3f68dc8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1102.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1102 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1102 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c index 6a6dc4f..c1eed44 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1103 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1150.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1150.c new file mode 100644 index 0000000..39d64ca --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1150.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1150 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1150 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1151.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1151.c new file mode 100644 index 0000000..2a0c732 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1151.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1151 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1151 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1152.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1152.c new file mode 100644 index 0000000..3c987dd --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1152.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1152 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1152 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1153.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1153.c new file mode 100644 index 0000000..7d38b82 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1153.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1153 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1153 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c index 3921bdd..07d1254 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c @@ -6,3 +6,20 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx9_4_generic \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available (as this is a generic config), + scan-offload-tree-dump will PASS - but linking fails with the + following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-generic.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-generic.c index 5aa8a2e..d6ba097 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-generic.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-generic.c @@ -6,3 +6,20 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx9_generic \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available (as this is a generic config), + scan-offload-tree-dump will PASS - but linking fails with the + following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c index f3f5244..37005fc 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx900 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx902.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx902.c new file mode 100644 index 0000000..82981c5 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx902.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx902 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx902 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx904.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx904.c new file mode 100644 index 0000000..89815fe --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx904.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx904 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx904 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c index ac43388..aeef690 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx906 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c index f60741f..799b546 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx908 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx909.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx909.c new file mode 100644 index 0000000..e8a6f63 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx909.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx909 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx909 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c index 832d174..de5626e 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx90a \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c index 44629a8..dfad7ec 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx90c \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c index d1df550..c8c7446 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c @@ -6,3 +6,28 @@ #include "declare-variant-4.h" /* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx942 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx950.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx950.c new file mode 100644 index 0000000..af81f11 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx950.c @@ -0,0 +1,33 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx950 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx950 \\(\\);" "optimized" } } */ + + +/* This code will link nicely if the multilib for that GPU architecture + has been build for GCC. In that case, scan-offload-tree-dump will + PASS and the linking will yield an XPASS message due to following line: */ + +/* { dg-excess-errors "ld: error: unable to find library -lgomp|gcn mkoffload: fatal error" } */ + +/* If the multi-lib config is not available, there are two options: + + * If the generic multi-lib is available, mkoffload fails early, + yielding UNRESOLVED for scan-offload-tree-dump and an XFAIL + for the message: + gcn mkoffload: fatal error: GCC was built without library support + for '-march=gfx...'; consider compiling for the associated + generic architecture '-march=gfx...-generic' instead + + * Or compling succeeds - then scan-offload-tree-dump will PASS - + but linking fails with the following error (XFAIL): + ld: error: unable to find library -lgomp + collect2: error: ld returned 1 exit status + gcn mkoffload: fatal error: ...-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status + compilation terminated. + lto-wrapper: fatal error: .../amdgcn-amdhsa/mkoffload returned 1 exit status + compilation terminated. */ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c216147..5c43bc0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,43 @@ +2025-10-16 Jonathan Wakely <jwakely@redhat.com> + + * include/std/stacktrace + (operator<<(ostream&, const stacktrace_entry&)): Improve output + when description() or source_file() returns an empty string, + or the stacktrace_entry is invalid. Append frame address to + output. + (operator<<(ostream&, const basic_stacktrace<A>&)): Use the + size_type of the correct specialization. + +2025-10-15 Jonathan Wakely <jwakely@redhat.com> + + * python/libstdcxx/v6/printers.py (StdStacktraceEntryPrinter): + New printer for std::stacktrace_entry. + (StdStacktracePrinter): New printer for std::basic_stacktrace. + +2025-10-15 Jonathan Wakely <jwakely@redhat.com> + + * include/std/stacktrace (basic_stacktrace::current): Call + _M_trim before returning. + (basic_stacktrace::_M_trim): New member function. + +2025-10-15 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/122293 + * include/bits/chrono.h (__to_timeout_timespec): Fix + preprocessor condition to match the conditions under which + callers of this function are defined. + * include/bits/this_thread_sleep.h: Remove unused include. + +2025-10-15 Chris Johns <chrisj@rtems.org> + + * configure: Regenerate. + * configure.ac (newlib, *-rtems*): Add HAVE_SYS_IOCTL_H, + HAVE_SYS_STAT_H, HAVE_SYS_TYPES_H, HAVE_S_ISREG, HAVE_UNISTD_H, + HAVE_UNLINKAT, _GLIBCXX_USE_CHMOD, _GLIBCXX_USE_MKDIR, + _GLIBCXX_USE_CHDIR, _GLIBCXX_USE_GETCWD, _GLIBCXX_USE_UTIME, + _GLIBCXX_USE_LINK, _GLIBCXX_USE_READLINK, _GLIBCXX_USE_SYMLINK, + _GLIBCXX_USE_TRUNCATE and _GLIBCXX_USE_FDOPENDIR. + 2025-10-14 Mike Crowe <mac@mcrowe.com> PR libstdc++/116586 diff --git a/libstdc++-v3/include/std/stacktrace b/libstdc++-v3/include/std/stacktrace index b9e260e..587a163 100644 --- a/libstdc++-v3/include/std/stacktrace +++ b/libstdc++-v3/include/std/stacktrace @@ -683,13 +683,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline ostream& operator<<(ostream& __os, const stacktrace_entry& __f) { + if (!__f) [[unlikely]] + return __os << "<unknown>"; + string __desc, __file; int __line; - if (__f._M_get_info(&__desc, &__file, &__line)) + if (__f._M_get_info(&__desc, &__file, &__line)) [[likely]] { - __os.width(4); - __os << __desc << " at " << __file << ':' << __line; + __os << ' '; + if (__desc.empty()) [[unlikely]] + __os << "<unknown>"; + else + __os << __desc; + if (!__file.empty()) [[likely]] + __os << " at " << __file << ':' << __line; } + + struct _Flag_guard // Set and restore hex format + { + _Flag_guard(ios& __s) : _M_ios(__s) { } + ~_Flag_guard() { _M_ios.setf(_M_f); } + + ios& _M_ios; + ios::fmtflags _M_f = _M_ios.setf(ios::hex, ios::basefield); + }; + _Flag_guard __g(__os); + __os << " [0x" << __f.native_handle() << ']'; return __os; } @@ -697,7 +716,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline ostream& operator<<(ostream& __os, const basic_stacktrace<_Allocator>& __st) { - for (stacktrace::size_type __i = 0; __i < __st.size(); ++__i) + using size_type = typename basic_stacktrace<_Allocator>::size_type; + for (size_type __i = 0, __size = __st.size(); __i < __size; ++__i) { __os.width(4); __os << __i << "# " << __st[__i] << '\n'; |