aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--contrib/ChangeLog4
-rw-r--r--contrib/gcc.doxy2
-rw-r--r--gcc/ChangeLog248
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/analyzer/ChangeLog9
-rw-r--r--gcc/analyzer/ana-state-to-diagnostic-state.cc166
-rw-r--r--gcc/analyzer/ana-state-to-diagnostic-state.h23
-rw-r--r--gcc/analyzer/checker-event.cc9
-rw-r--r--gcc/analyzer/sm-malloc.cc29
-rw-r--r--gcc/config/rs6000/aix.h4
-rwxr-xr-xgcc/configure2
-rw-r--r--gcc/configure.ac2
-rw-r--r--gcc/custom-sarif-properties/digraphs.cc28
-rw-r--r--gcc/custom-sarif-properties/digraphs.h37
-rw-r--r--gcc/custom-sarif-properties/state-graphs.cc161
-rw-r--r--gcc/custom-sarif-properties/state-graphs.h98
-rw-r--r--gcc/diagnostics/diagnostics-selftests.cc1
-rw-r--r--gcc/diagnostics/diagnostics-selftests.h1
-rw-r--r--gcc/diagnostics/digraphs.cc199
-rw-r--r--gcc/diagnostics/digraphs.h62
-rw-r--r--gcc/diagnostics/html-sink.cc62
-rw-r--r--gcc/diagnostics/html-sink.h9
-rw-r--r--gcc/diagnostics/output-spec.cc12
-rw-r--r--gcc/diagnostics/state-graphs-to-dot.cc141
-rw-r--r--gcc/diagnostics/state-graphs.cc156
-rw-r--r--gcc/diagnostics/state-graphs.h108
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/json.cc25
-rw-r--r--gcc/json.h82
-rw-r--r--gcc/testsuite/ChangeLog47
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc5
-rw-r--r--gcc/tree-vect-loop.cc4
-rw-r--r--include/ChangeLog6
-rw-r--r--include/dwarf2.def4
-rw-r--r--libgomp/ChangeLog45
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c17
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1030.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1031.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1032.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1033.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1034.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1035.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx11-generic.c17
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1100.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1101.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1102.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1150.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1151.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1152.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx1153.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-4-generic.c17
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx9-generic.c17
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx902.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx904.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx909.c33
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c25
-rw-r--r--libgomp/testsuite/libgomp.c/declare-variant-4-gfx950.c33
-rw-r--r--libstdc++-v3/ChangeLog40
-rw-r--r--libstdc++-v3/include/std/stacktrace28
68 files changed, 2161 insertions, 529 deletions
diff --git a/ChangeLog b/ChangeLog
index 6874702..241d28e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 &reg)
{
auto existing = m_region_to_state_node_map.find (&reg);
if (existing != m_region_to_state_node_map.end ())
return *existing->second;
- auto ref = create_and_add_state_node (reg);
- m_region_to_state_node_map[&reg] = &ref.m_node;
- return ref;
+ auto &state_node = create_and_add_state_node (reg);
+ m_region_to_state_node_map[&reg] = &state_node;
+ return state_node;
}
-state_node_ref
+diagnostics::digraphs::node &
analyzer_state_graph::create_and_add_state_node (const region &reg)
{
auto node = create_state_node (reg);
- state_node_ref result = *node;
+ diagnostics::digraphs::node &result = *node;
if (auto parent_reg = reg.get_parent_region ())
if (parent_reg->get_kind () != RK_ROOT)
{
- auto parent_state_node = get_or_create_state_node (*parent_reg);
- parent_state_node.m_node.add_child (std::move (node));
+ auto &parent_state_node = get_or_create_state_node (*parent_reg);
+ parent_state_node.add_child (std::move (node));
return result;
}
add_node (std::move (node));
@@ -264,19 +281,18 @@ analyzer_state_graph::make_node_id (const region &reg)
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::
-make_state_node (diagnostics::state_graphs::node_kind kind,
+make_state_node (enum node_properties::kind_t kind,
std::string id)
{
auto node = std::make_unique<diagnostics::digraphs::node> (*this, std::move (id));
- state_node_ref node_ref (*node);
- node_ref.set_node_kind (kind);
+ node->set_property (node_properties::kind_prop, kind);
return node;
}
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::
make_memspace_state_node (const region &reg,
- diagnostics::state_graphs::node_kind kind)
+ enum node_properties::kind_t kind)
{
return make_state_node (kind, make_node_id (reg));
}
@@ -296,7 +312,7 @@ analyzer_state_graph::create_state_node (const region &reg)
const frame_region &frame_reg
= static_cast<const frame_region &> (reg);
- node = make_state_node (diagnostics::state_graphs::node_kind::stack_frame,
+ node = make_state_node (node_properties::kind_t::stack_frame,
make_node_id (reg));
node->set_logical_loc
(m_logical_loc_mgr.key_from_tree (frame_reg.get_fndecl ()));
@@ -304,58 +320,59 @@ analyzer_state_graph::create_state_node (const region &reg)
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%E", frame_reg.get_fndecl ());
- node->set_attr (STATE_NODE_PREFIX, "function",
- pp_formatted_text (&pp));
+ node->set_property (node_properties::function,
+ pp_formatted_text (&pp));
}
}
break;
case RK_GLOBALS:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::globals);
+ node_properties::kind_t::globals);
break;
case RK_CODE:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::code);
+ node_properties::kind_t::code);
break;
case RK_FUNCTION:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::function);
+ node_properties::kind_t::function);
// TODO
break;
case RK_STACK:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::stack);
+ node_properties::kind_t::stack);
break;
case RK_HEAP:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::heap_);
+ node_properties::kind_t::heap_);
break;
case RK_THREAD_LOCAL:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::thread_local_);
+ node_properties::kind_t::thread_local_);
break;
case RK_ROOT:
gcc_unreachable ();
break;
case RK_SYMBOLIC:
node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::other);
+ node_properties::kind_t::other);
break;
case RK_DECL:
{
- node = make_state_node (diagnostics::state_graphs::node_kind::variable,
+ node = make_state_node (node_properties::kind_t::variable,
make_node_id (reg));
const decl_region &decl_reg
= static_cast<const decl_region &> (reg);
- state_node_ref node_ref (*node);
+
{
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%E", decl_reg.get_decl ());
- node_ref.set_name (pp_formatted_text (&pp));
+ node->set_property (node_properties::name,
+ pp_formatted_text (&pp));
}
set_type_attr (*node, TREE_TYPE (decl_reg.get_decl ()));
}
@@ -377,14 +394,15 @@ analyzer_state_graph::create_state_node (const region &reg)
case RK_ERRNO:
case RK_PRIVATE:
case RK_UNKNOWN:
- node = make_state_node (diagnostics::state_graphs::node_kind::other,
+ node = make_state_node (node_properties::kind_t::other,
make_node_id (reg));
break;
case RK_HEAP_ALLOCATED:
case RK_ALLOCA:
- node = make_memspace_state_node (reg,
- diagnostics::state_graphs::node_kind::dynalloc_buffer);
+ node
+ = make_memspace_state_node (reg,
+ node_properties::kind_t::dynalloc_buffer);
set_attr_for_dynamic_extents (reg, *node);
break;
}
@@ -425,9 +443,9 @@ create_state_nodes_for_binding_cluster (const binding_cluster &cluster,
get_or_create_state_node (*reg);
}
- auto ref = get_or_create_state_node (*cluster.get_base_region ());
+ auto &ref = get_or_create_state_node (*cluster.get_base_region ());
- ref.m_node.add_child (create_state_node_for_conc_bindings (conc_bindings));
+ ref.add_child (create_state_node_for_conc_bindings (conc_bindings));
const region *typed_reg = cluster.get_base_region ();
if (!typed_reg->get_type ())
@@ -455,23 +473,18 @@ create_state_nodes_for_binding_cluster (const binding_cluster &cluster,
std::unique_ptr<diagnostics::digraphs::node>
analyzer_state_graph::create_state_node_for_conc_bindings (const concrete_bindings_t &conc_bindings)
{
- auto node = make_state_node (diagnostics::state_graphs::node_kind::other,
+ auto node = make_state_node (node_properties::kind_t::other,
make_node_id ("concrete-bindings"));
for (auto iter : conc_bindings)
{
const bit_range bits = iter.first;
const svalue *sval = iter.second;
auto binding_state_node
- = make_state_node (diagnostics::state_graphs::node_kind::other,
+ = make_state_node (node_properties::kind_t::other,
make_node_id ("binding"));
set_bits_attr (*binding_state_node, bits);
- {
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- sval->dump_to_pp (&pp, true);
- binding_state_node->set_attr (STATE_NODE_PREFIX, "value",
- pp_formatted_text (&pp));
- }
+ gcc_assert (sval);
+ set_value_attrs (*binding_state_node, *sval);
node->add_child (std::move (binding_state_node));
}
return node;
@@ -496,27 +509,28 @@ analyzer_state_graph::get_bit_range_within_base_region (const region &reg,
void
analyzer_state_graph::
-populate_state_node_for_typed_region (state_node_ref node,
+populate_state_node_for_typed_region (diagnostics::digraphs::node &state_node,
const region &reg,
const concrete_bindings_t &conc_bindings,
bool create_all)
{
const_tree reg_type = reg.get_type ();
gcc_assert (reg_type);
- set_type_attr (node, reg_type);
+ set_type_attr (state_node, reg_type);
bit_range bits (0, 0);
if (get_bit_range_within_base_region (reg, bits))
{
- set_bits_attr (node, bits);
+ set_bits_attr (state_node, bits);
auto search = conc_bindings.find (bits);
if (search != conc_bindings.end ())
{
const svalue *bound_sval = search->second;
- node.set_json_attr ("value", bound_sval->to_json ());
+ gcc_assert (bound_sval);
+ set_value_attrs (state_node, *bound_sval);
if (const region *dst_reg = bound_sval->maybe_get_region ())
- m_pending_edges.push_back ({node, *dst_reg});
+ m_pending_edges.push_back ({state_node, *dst_reg});
}
}
@@ -555,9 +569,10 @@ populate_state_node_for_typed_region (state_node_ref node,
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::element,
+ (node_properties::kind_t::element,
make_node_id (*child_reg));
- set_wi_attr (*child_state_node, "index", idx, UNSIGNED);
+ set_wi_attr (*child_state_node,
+ node_properties::index, idx, UNSIGNED);
// Recurse:
gcc_assert (element_type);
@@ -565,7 +580,7 @@ populate_state_node_for_typed_region (state_node_ref node,
*child_reg,
conc_bindings,
create_all);
- node.m_node.add_child (std::move (child_state_node));
+ state_node.add_child (std::move (child_state_node));
}
}
}
@@ -587,11 +602,12 @@ populate_state_node_for_typed_region (state_node_ref node,
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::padding,
+ (node_properties::kind_t::padding,
make_node_id (*child_reg));
- set_wi_attr (*child_state_node, "num_bits",
+ set_wi_attr (*child_state_node,
+ node_properties::num_bits,
item.m_bit_range.m_size_in_bits, SIGNED);
- node.m_node.add_child (std::move (child_state_node));
+ state_node.add_child (std::move (child_state_node));
}
}
else
@@ -600,27 +616,27 @@ populate_state_node_for_typed_region (state_node_ref node,
= m_mgr.get_field_region (&reg,
const_cast<tree> (item.m_field));
if (show_child_state_node_for_child_region_p (*child_reg,
- conc_bindings,
- create_all))
+ conc_bindings,
+ create_all))
{
auto child_state_node
= make_state_node
- (diagnostics::state_graphs::node_kind::field,
+ (node_properties::kind_t::field,
make_node_id (*child_reg));
{
pretty_printer pp;
pp_format_decoder (&pp) = default_tree_printer;
pp_printf (&pp, "%D", item.m_field);
- child_state_node->set_attr (STATE_NODE_PREFIX, "name",
- pp_formatted_text (&pp));
+ child_state_node->set_property (node_properties::name,
+ pp_formatted_text (&pp));
}
// Recurse:
populate_state_node_for_typed_region (*child_state_node,
- *child_reg,
- conc_bindings,
- create_all);
- node.m_node.add_child (std::move (child_state_node));
+ *child_reg,
+ conc_bindings,
+ create_all);
+ state_node.add_child (std::move (child_state_node));
}
}
}
@@ -630,8 +646,9 @@ populate_state_node_for_typed_region (state_node_ref node,
}
void
-analyzer_state_graph::set_attr_for_dynamic_extents (const region &reg,
- state_node_ref node_ref)
+analyzer_state_graph::
+set_attr_for_dynamic_extents (const region &reg,
+ diagnostics::digraphs::node &state_node)
{
const svalue *sval = m_state.m_region_model->get_dynamic_extents (&reg);
if (sval)
@@ -642,15 +659,16 @@ analyzer_state_graph::set_attr_for_dynamic_extents (const region &reg,
pp_wide_int (&pp, wi::to_wide (cst), UNSIGNED);
else
sval->dump_to_pp (&pp, true);
- node_ref.set_attr ("dynamic-extents", pp_formatted_text (&pp));
+ state_node.set_property (state_node_properties::dynamic_extents,
+ pp_formatted_text (&pp));
}
}
bool
analyzer_state_graph::
show_child_state_node_for_child_region_p (const region &reg,
- const concrete_bindings_t &conc_bindings,
- bool create_all)
+ const concrete_bindings_t &conc_bindings,
+ bool create_all)
{
if (create_all)
return true;
diff --git a/gcc/analyzer/ana-state-to-diagnostic-state.h b/gcc/analyzer/ana-state-to-diagnostic-state.h
index 3a5ccc1..272a4d7 100644
--- a/gcc/analyzer/ana-state-to-diagnostic-state.h
+++ b/gcc/analyzer/ana-state-to-diagnostic-state.h
@@ -23,34 +23,38 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostics/state-graphs.h"
#include "tree-logical-location.h"
+#include "custom-sarif-properties/state-graphs.h"
namespace ana {
+namespace state_node_properties = custom_sarif_properties::state_graphs::node;
+
class analyzer_state_graph : public diagnostics::digraphs::digraph
{
public:
analyzer_state_graph (const program_state &state,
const extrinsic_state &ext_state);
- diagnostics::state_graphs::state_node_ref
+ diagnostics::digraphs::node &
get_or_create_state_node (const region &reg);
private:
+
struct pending_edge
{
- diagnostics::state_graphs::state_node_ref m_src_node;
+ diagnostics::digraphs::node & m_src_node;
const region &m_dst_reg;
};
-
- diagnostics::state_graphs::state_node_ref
+
+ diagnostics::digraphs::node &
create_and_add_state_node (const region &reg);
std::unique_ptr<diagnostics::digraphs::node>
- make_state_node (diagnostics::state_graphs::node_kind kind,
+ make_state_node (enum state_node_properties::kind_t kind,
std::string id);
std::unique_ptr<diagnostics::digraphs::node>
make_memspace_state_node (const region &reg,
- enum diagnostics::state_graphs::node_kind kind);
+ enum state_node_properties::kind_t kind);
std::unique_ptr<diagnostics::digraphs::node>
create_state_node (const region &reg);
@@ -71,14 +75,14 @@ private:
bit_range &out);
void
- populate_state_node_for_typed_region (diagnostics::state_graphs::state_node_ref,
+ populate_state_node_for_typed_region (diagnostics::digraphs::node &,
const region &reg,
const concrete_bindings_t &conc_bindings,
bool create_all);
void
set_attr_for_dynamic_extents (const region &reg,
- diagnostics::state_graphs::state_node_ref);
+ diagnostics::digraphs::node &);
bool
show_child_state_node_for_child_region_p (const region &reg,
@@ -95,7 +99,8 @@ private:
const program_state &m_state;
const extrinsic_state &m_ext_state;
region_model_manager &m_mgr;
- std::map<const region *, diagnostics::digraphs::node *> m_region_to_state_node_map;
+ std::map<const region *,
+ diagnostics::digraphs::node *> m_region_to_state_node_map;
std::map<const region *, tree> m_types_for_untyped_regions;
unsigned m_next_id;
std::vector<pending_edge> m_pending_edges;
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 4eac945..790ebc7 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-logical-location.h"
#include "diagnostics/sarif-sink.h"
#include "diagnostics/state-graphs.h"
+#include "custom-sarif-properties/state-graphs.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
@@ -242,9 +243,11 @@ checker_event::maybe_make_diagnostic_state_graph (bool debug) const
pretty_printer pp;
text_art::theme *theme = global_dc->get_diagram_theme ();
text_art::dump_to_pp (*state, theme, &pp);
- result->set_attr (STATE_GRAPH_PREFIX,
- "analyzer/program_state/",
- pp_formatted_text (&pp));
+ const json::string_property program_state_property
+ (custom_sarif_properties::state_graphs::graph::prefix,
+ "analyzer/program_state/");
+ result->set_property (program_state_property,
+ pp_formatted_text (&pp));
}
return result;
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index a6b1421..8ce7710 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -2735,7 +2735,7 @@ malloc_state_machine::transition_ptr_sval_non_null (region_model *model,
smap->set_state (model, new_ptr_sval, m_free.m_nonnull, nullptr, ext_state);
}
-static enum diagnostics::state_graphs::node_dynalloc_state
+static enum custom_sarif_properties::state_graphs::node::dynalloc_state_t
get_dynalloc_state_for_state (enum resource_state rs)
{
switch (rs)
@@ -2746,17 +2746,17 @@ get_dynalloc_state_for_state (enum resource_state rs)
case RS_NULL:
case RS_NON_HEAP:
case RS_STOP:
- return diagnostics::state_graphs::node_dynalloc_state::unknown;
+ return state_node_properties::dynalloc_state_t::unknown;
case RS_ASSUMED_NON_NULL:
- return diagnostics::state_graphs::node_dynalloc_state::nonnull;
+ return state_node_properties::dynalloc_state_t::nonnull;
case RS_UNCHECKED:
- return diagnostics::state_graphs::node_dynalloc_state::unchecked;
+ return state_node_properties::dynalloc_state_t::unchecked;
case RS_NONNULL:
- return diagnostics::state_graphs::node_dynalloc_state::nonnull;
+ return state_node_properties::dynalloc_state_t::nonnull;
case RS_FREED:
- return diagnostics::state_graphs::node_dynalloc_state::freed;
+ return state_node_properties::dynalloc_state_t::freed;
}
}
@@ -2768,24 +2768,23 @@ add_state_to_state_graph (analyzer_state_graph &out_state_graph,
{
if (const region *reg = sval.maybe_get_region ())
{
- auto reg_node = out_state_graph.get_or_create_state_node (*reg);
+ auto &reg_node = out_state_graph.get_or_create_state_node (*reg);
auto alloc_state = as_a_allocation_state (state);
gcc_assert (alloc_state);
- reg_node.set_dynalloc_state
- (get_dynalloc_state_for_state (alloc_state->m_rs));
+ reg_node.set_property (state_node_properties::dynalloc_state_prop,
+ get_dynalloc_state_for_state (alloc_state->m_rs));
+
if (alloc_state->m_deallocators)
{
pretty_printer pp;
alloc_state->m_deallocators->dump_to_pp (&pp);
- reg_node.m_node.set_attr (STATE_NODE_PREFIX,
- "expected-deallocators",
- pp_formatted_text (&pp));
+ reg_node.set_property (state_node_properties::expected_deallocators,
+ pp_formatted_text (&pp));
}
if (alloc_state->m_deallocator)
- reg_node.m_node.set_attr (STATE_NODE_PREFIX,
- "deallocator",
- alloc_state->m_deallocator->m_name);
+ reg_node.set_property (state_node_properties::deallocator,
+ alloc_state->m_deallocator->m_name);
}
}
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
diff --git a/gcc/json.h b/gcc/json.h
index c706f2a..c53715e 100644
--- a/gcc/json.h
+++ b/gcc/json.h
@@ -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';