diff --git a/gcc.spec b/gcc.spec index e05a5f5..0acaa01 100644 --- a/gcc.spec +++ b/gcc.spec @@ -5,7 +5,7 @@ %global gcc_major 11 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 14 +%global gcc_release 15 %global nvptx_tools_gitrev 5f6f343a302d620b0868edab376c00b15741e39e %global newlib_cygwin_gitrev 50e2a63b04bdd018484605fbb954fd1bd5147fa0 %global _unpackaged_files_terminate_build 0 @@ -347,6 +347,8 @@ Patch109: gcc11-fortran-fdec-add-missing-indexes.patch Patch1000: gcc11-libstdc++-prettyprinter-update-15.patch Patch1001: gcc11-libstdc++-prettyprinter-update-15-tests.patch Patch1002: gcc11-libstdc++-prettyprinter-update-15-tests-48362.patch +Patch1003: gcc11-libstdc++-prettyprinter-update-16.patch +Patch1004: gcc11-libstdc++-prettyprinter-update-16-tests.patch # Backports Patch2000: gcc11-fix-failures-with-default-SSP.patch @@ -1071,6 +1073,8 @@ mark them as cross compiled. %patch1000 -p1 -b .libstdc++-prettyprinter-update-15 %patch1001 -p1 -b .libstdc++-prettyprinter-update-15-tests %patch1002 -p1 -b .libstdc++-prettyprinter-update-15-tests-48362 +%patch1003 -p1 -b .libstdc++-prettyprinter-update-16 +%patch1004 -p1 -b .libstdc++-prettyprinter-update-16-tests %patch2000 -p1 -b .fix-failures-with-default-SSP %patch2001 -p1 -b .disable-stack-protector-for-tests-relying-on-stack-offset @@ -3871,6 +3875,9 @@ end %endif %changelog +* Thu Jul 09 2026 Siddhesh Poyarekar - 11.5.0-15 +- Update libstdc++ pretty printers from GCC 16 GTS (RHEL-169098) + * Thu Oct 30 2025 David Malcolm - 11.5.0-14 - Add backport of upstream r15-8946-g580664d1b66a5d to gcc 11, adding branches and calls to gcov output, but not conditions (RHEL-105416). diff --git a/gcc11-libstdc++-prettyprinter-update-16-tests.patch b/gcc11-libstdc++-prettyprinter-update-16-tests.patch new file mode 100644 index 0000000..d2b0167 --- /dev/null +++ b/gcc11-libstdc++-prettyprinter-update-16-tests.patch @@ -0,0 +1,120 @@ + .../testsuite/libstdc++-prettyprinters/compat.cc | 36 +++++++++++++++++++++- + .../testsuite/libstdc++-prettyprinters/cxx11.cc | 2 +- + .../testsuite/libstdc++-prettyprinters/cxx17.cc | 2 +- + .../libstdc++-prettyprinters/filesystem-ts.cc | 2 +- + .../libstdc++-prettyprinters/libfundts.cc | 2 +- + 5 files changed, 39 insertions(+), 5 deletions(-) + +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc +index 2ef5979834f..35ec5cf2398 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc +@@ -1,7 +1,7 @@ + // { dg-options "-g -O0" } + // { dg-do run { target c++11 } } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -88,6 +88,30 @@ namespace std + this->_M_payload._M_engaged = true; + } + }; ++ ++ using uintptr_t = __UINTPTR_TYPE__; ++ template struct shared_ptr; ++ template struct atomic; ++ template<> struct atomic { uintptr_t _M_i; }; ++ template struct sp_atomic; ++ struct sp_counts { int _M_use_count; int _M_weak_count; }; ++ ++ // Old representation of std::atomic>, before GCC 16 ++ template ++ struct sp_atomic> ++ { ++ T* _M_ptr = nullptr; ++ struct Impl { ++ atomic _M_val; ++ using pointer = sp_counts*; ++ } _M_refcount; ++ }; ++ template ++ struct atomic> ++ { ++ sp_atomic> _M_impl; ++ }; ++ + } // namespace std + + int +@@ -110,6 +134,16 @@ main() + optional op{nullptr}; + // { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } } + ++ std::atomic> aspe{}; ++// { dg-final { note-test aspe {std::atomic> (empty) = {get() = 0x0}} } } ++ ++ std::sp_counts counts{ 1, 3 }; ++ std::sp_atomic>::Impl::pointer p = &counts; ++ std::atomic> asp{}; ++ asp._M_impl._M_ptr = reinterpret_cast(0x1234abcd); ++ asp._M_impl._M_refcount._M_val._M_i = reinterpret_cast(p); ++// { dg-final { note-test asp {std::atomic> (use count 1, weak count 2) = {get() = 0x1234abcd}} } } ++ + __builtin_puts(""); + return 0; // Mark SPOT + } +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +index 23f6d97ddd4..61ea24e7bb2 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +@@ -1,7 +1,7 @@ + // { dg-do run { target c++11 } } + // { dg-options "-g -O0" } + +-// Copyright (C) 2011-2025 Free Software Foundation, Inc. ++// Copyright (C) 2011-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc +index 6dd2b60c0a5..3a8dd925dd6 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc +@@ -1,7 +1,7 @@ + // { dg-options "-g -O0" } + // { dg-do run { target c++17 } } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc +index 3221f2df90d..0bae706c9a3 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc +@@ -2,7 +2,7 @@ + // { dg-do run { target c++11 } } + // { dg-require-filesystem-ts "" } + +-// Copyright (C) 2020-2025 Free Software Foundation, Inc. ++// Copyright (C) 2020-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +index bfb86885457..265fd6ffafe 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +@@ -1,7 +1,7 @@ + // { dg-do run { target c++14 } } + // { dg-options "-g -O0" } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the diff --git a/gcc11-libstdc++-prettyprinter-update-16.patch b/gcc11-libstdc++-prettyprinter-update-16.patch new file mode 100644 index 0000000..25f1053 --- /dev/null +++ b/gcc11-libstdc++-prettyprinter-update-16.patch @@ -0,0 +1,291 @@ + libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 +- + libstdc++-v3/python/libstdcxx/v6/printers.py | 119 ++++++++++++++++++++++++--- + libstdc++-v3/python/libstdcxx/v6/xmethods.py | 9 +- + 3 files changed, 110 insertions(+), 20 deletions(-) + +diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py b/libstdc++-v3/python/libstdcxx/v6/__init__.py +index 5a8f2de195d..c46c92739bb 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/__init__.py ++++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py +@@ -1,4 +1,4 @@ +-# Copyright (C) 2014-2025 Free Software Foundation, Inc. ++# Copyright (C) 2014-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py +index 052a99a28ed..be7e7a25606 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/printers.py ++++ b/libstdc++-v3/python/libstdcxx/v6/printers.py +@@ -1,6 +1,6 @@ + # Pretty-printers for libstdc++. + +-# Copyright (C) 2008-2025 Free Software Foundation, Inc. ++# Copyright (C) 2008-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -291,7 +291,17 @@ class SharedPointerPrinter(printer_base): + def _get_refcounts(self): + if self._typename == 'std::atomic': + # A tagged pointer is stored as uintptr_t. +- ptr_val = self._val['_M_refcount']['_M_val']['_M_i'] ++ val = self._val['_M_refcount']['_M_val'] ++ # GCC 16 stores it directly as uintptr_t ++ # GCC 12-15 stores std::atomic ++ if hasattr(val.type, 'is_scalar'): # Added in GDB 12.1 ++ val_is_uintptr = val.type.is_scalar ++ else: ++ val_is_uintptr = val.type.tag is None ++ if val_is_uintptr: ++ ptr_val = val ++ else: ++ ptr_val = val['_M_i'] + ptr_val = ptr_val - (ptr_val % 2) # clear lock bit + ptr_type = find_type(self._val['_M_refcount'].type, 'pointer') + return ptr_val.cast(ptr_type) +@@ -572,7 +582,10 @@ class StdVectorPrinter(printer_base): + self._val['_M_impl']['_M_finish'], + self._is_bool) + +- def to_string(self): ++ # Helper to compute the bounds of the vector. ++ # Returns a tuple: (length, capacity, suffix) ++ # SUFFIX is a type-name suffix to print. ++ def _bounds(self): + start = self._val['_M_impl']['_M_start'] + finish = self._val['_M_impl']['_M_finish'] + end = self._val['_M_impl']['_M_end_of_storage'] +@@ -582,13 +595,27 @@ class StdVectorPrinter(printer_base): + fo = self._val['_M_impl']['_M_finish']['_M_offset'] + itype = start.dereference().type + bl = 8 * itype.sizeof +- length = bl * (finish - start) + fo +- capacity = bl * (end - start) +- return ('%s of length %d, capacity %d' +- % (self._typename, int(length), int(capacity))) ++ length = int(bl * (finish - start) + fo) ++ capacity = int(bl * (end - start)) ++ suffix = '' + else: +- return ('%s of length %d, capacity %d' +- % (self._typename, int(finish - start), int(end - start))) ++ length = int(finish - start) ++ capacity = int(end - start) ++ suffix = '' ++ if length < 0: ++ # Probably uninitialized. ++ length = 0 ++ capacity = 0 ++ return (length, capacity, suffix) ++ ++ def to_string(self): ++ (length, capacity, suffix) = self._bounds() ++ return ('%s%s of length %d, capacity %d' ++ % (self._typename, suffix, length, capacity)) ++ ++ def num_children(self): ++ (length, capacity, suffix) = self._bounds() ++ return length + + def display_hint(self): + return 'array' +@@ -733,6 +760,11 @@ class StdStackOrQueuePrinter(printer_base): + return '%s wrapping: %s' % (self._typename, + self._visualizer.to_string()) + ++ def num_children(self): ++ if hasattr(self._visualizer, 'num_children'): ++ return self._visualizer.num_children() ++ return None ++ + def display_hint(self): + if hasattr(self._visualizer, 'display_hint'): + return self._visualizer.display_hint() +@@ -876,6 +908,9 @@ class StdMapPrinter(printer_base): + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer() + return self._iter(RbtreeIterator(self._val), node) + ++ def num_children(slf): ++ return len(RbtreeIterator(self._val)) ++ + def display_hint(self): + return 'map' + +@@ -915,6 +950,8 @@ class StdSetPrinter(printer_base): + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer() + return self._iter(RbtreeIterator(self._val), node) + ++ def num_children(slf): ++ return len(RbtreeIterator(self._val)) + + class StdBitsetPrinter(printer_base): + """Print a std::bitset.""" +@@ -1006,7 +1043,8 @@ class StdDequePrinter(printer_base): + else: + self._buffer_size = 1 + +- def to_string(self): ++ # Helper to compute the size. ++ def _size(self): + start = self._val['_M_impl']['_M_start'] + end = self._val['_M_impl']['_M_finish'] + +@@ -1014,9 +1052,11 @@ class StdDequePrinter(printer_base): + delta_s = start['_M_last'] - start['_M_cur'] + delta_e = end['_M_cur'] - end['_M_first'] + +- size = self._buffer_size * delta_n + delta_s + delta_e ++ return long(self._buffer_size * delta_n + delta_s + delta_e) + +- return '%s with %s' % (self._typename, num_elements(long(size))) ++ def to_string(self): ++ size = self._size() ++ return '%s with %s' % (self._typename, num_elements(size)) + + def children(self): + start = self._val['_M_impl']['_M_start'] +@@ -1024,6 +1064,9 @@ class StdDequePrinter(printer_base): + return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'], + end['_M_cur'], self._buffer_size) + ++ def num_children(self): ++ return self._size() ++ + def display_hint(self): + return 'array' + +@@ -1210,6 +1253,9 @@ class Tr1UnorderedSetPrinter(printer_base): + return izip(counter, Tr1HashtableIterator(self._hashtable())) + return izip(counter, StdHashtableIterator(self._hashtable())) + ++ def num_children(self): ++ return int(self._hashtable()['_M_element_count']) ++ + + class Tr1UnorderedMapPrinter(printer_base): + """Print a std::unordered_map or tr1::unordered_map.""" +@@ -1254,6 +1300,9 @@ class Tr1UnorderedMapPrinter(printer_base): + # Zip the two iterators together. + return izip(counter, data) + ++ def num_children(self): ++ return int(self._hashtable()['_M_element_count']) ++ + def display_hint(self): + return 'map' + +@@ -1753,7 +1802,11 @@ class StdCmpCatPrinter(printer_base): + if self._typename == 'strong_ordering' and self._val == 0: + name = 'equal' + else: +- names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'} ++ names = { ++ -1: 'less', 0: 'equivalent', 1: 'greater', ++ # GCC 10-15 used 2 for unordered ++ -128: 'unordered', 2: 'unordered' ++ } + name = names[int(self._val)] + return 'std::{}::{}'.format(self._typename, name) + +@@ -1945,6 +1998,9 @@ class StdSpanPrinter(printer_base): + def children(self): + return self._iterator(self._val['_M_ptr'], self._size) + ++ def num_children(self): ++ return int(self._size) ++ + def display_hint(self): + return 'array' + +@@ -2353,6 +2409,37 @@ class StdTextEncodingPrinter(printer_base): + return 'unknown' + return rep['_M_name'] + ++class StdStacktraceEntryPrinter(printer_base): ++ """Print a std::stacktrace_entry.""" ++ ++ def __init__(self, typename, val): ++ self._val = val ++ self._typename = typename ++ ++ def to_string(self): ++ block = gdb.current_progspace().block_for_pc(self._val['_M_pc']) ++ if block is None or block.function is None: ++ return "" ++ sym = block.function ++ return "{{{} at {}:{}}}".format(sym.print_name, sym.symtab.filename, sym.line) ++ ++class StdStacktracePrinter(printer_base): ++ """Print a std::stacktrace.""" ++ ++ def __init__(self, typename, val): ++ self._val = val ++ self._typename = typename ++ self._size = self._val['_M_impl']['_M_size'] ++ ++ def to_string(self): ++ return '%s of length %d' % (self._typename, self._size) ++ ++ def children(self): ++ return StdSpanPrinter._iterator(self._val['_M_impl']['_M_frames'], self._size) ++ ++ def display_hint(self): ++ return 'array' ++ + # A "regular expression" printer which conforms to the + # "SubPrettyPrinter" protocol from gdb.printing. + class RxPrinter(object): +@@ -2973,6 +3060,12 @@ def build_libstdcxx_dictionary(): + # libstdcxx_printer.add_version('std::chrono::(anonymous namespace)', 'Rule', + # StdChronoTimeZoneRulePrinter) + ++ # C++23 components ++ libstdcxx_printer.add_version('std::', 'stacktrace_entry', ++ StdStacktraceEntryPrinter) ++ libstdcxx_printer.add_version('std::', 'basic_stacktrace', ++ StdStacktracePrinter) ++ + # C++26 components + libstdcxx_printer.add_version('std::', 'text_encoding', + StdTextEncodingPrinter) +diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py +index 109ca10956a..5d1eb375dc3 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py ++++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py +@@ -1,6 +1,6 @@ + # Xmethods for libstdc++. + +-# Copyright (C) 2014-2025 Free Software Foundation, Inc. ++# Copyright (C) 2014-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -28,8 +28,6 @@ def get_bool_type(): + def get_std_size_type(): + return gdb.lookup_type('std::size_t') + +-_versioned_namespace = '__8::' +- + def is_specialization_of(x, template_name): + """ + Test whether a type is a specialization of the named class template. +@@ -39,8 +37,7 @@ def is_specialization_of(x, template_name): + """ + if isinstance(x, gdb.Type): + x = x.tag +- template_name = '(%s)?%s' % (_versioned_namespace, template_name) +- return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None ++ return re.match(r'^std::(__\d::|__debug::)?%s<.*>$' % template_name, x) is not None + + class LibStdCxxXMethod(gdb.xmethod.XMethod): + def __init__(self, name, worker_class): +@@ -445,7 +442,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): + if method is None or not method.enabled: + return None + val_type = class_type.template_argument(0) +- node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer() ++ node_type = gdb.lookup_type(str(class_type) + '::_Node_ptr') + return method.worker_class(val_type, node_type) + + # Xmethods for std::vector