This consolidates the three static archives for extensions into one, so
that -lstdc++exp can be used to provide the definitions of all unstable
library features.
The libstdc++_libbacktrace.a archive is now just a "noinst" convenience
library that is only used during the build, not installed. Its contents
are added to libstdc++exp.a, along with the new non-inline definitions
of std::stacktrace symbols.
The libstdc++fs.a archive is still installed, but its contents are
duplicated in libstdc++exp.a now. This means -lstdc++exp can be used
instead of -lstdc++fs. For targets using the GNU linker we should
consider replacing libstdc++fs.a with a linker script that does
INPUT(libstdc++exp.a).
The tests for <experimental/filesystem> could be changed to use
-lstdc++exp instead of -lstdc++fs, which would allow removing
src/filesystem/.libs from the LDFLAGS in scripts/testsuite_flags.in,
but that can be done at a later date.
libstdc++-v3/ChangeLog:
* acinclude.m4 (GLIBCXX_CONFIGURE): Add c++23 directory.
* configure: Regenerate.
* doc/html/manual/*: Regenerate.
* doc/xml/manual/using.xml: Update documentation on linking.
* include/std/stacktrace: Remove declarations of libbacktrace
APIs.
(stacktrace_entry::_S_err_handler, stacktrace_entry::_S_init):
Remove.
(stacktrace_entry::_Info): New class.
(stacktrace_entry::_M_get_info): Use _Info.
(__stacktrace_impl): New class.
(basic_stacktrace): Derive from __stacktrace_impl.
(basic_stacktrace::current): Use __stacktrace_impl::_S_current.
* scripts/testsuite_flags.in: Adjust LDFLAGS to find
libstdc++exp instead of libstdc++_libbacktrace.
* src/Makefile.am (SUBDIRS): Add c++23 directory.
* src/Makefile.in: Regenerate.
* src/c++20/Makefile.am: Fix comment.
* src/c++20/Makefile.in: Regenerate.
* src/c++23/Makefile.am: New file.
* src/c++23/Makefile.in: New file.
* src/c++23/stacktrace.cc: New file with definitions of
stacktrace_entry::_Info and __stacktrace_impl members.
* src/experimental/Makefile.am: Use LIBADD to include other
libraries.
* src/experimental/Makefile.in: Regenerate.
* src/libbacktrace/Makefile.am: Use noinst_LTLIBRARIES.
* src/libbacktrace/Makefile.in: Regenerate.
* testsuite/19_diagnostics/stacktrace/current.cc: Adjust
dg-options to use -lstdc++exp.
* testsuite/19_diagnostics/stacktrace/entry.cc: Likewise.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Likewise.
* testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc:
Likewise.
---
libstdc++-v3/acinclude.m4 | 2 +-
libstdc++-v3/configure | 16 +-
libstdc++-v3/doc/html/manual/using.html | 26 +-
.../html/manual/using_dynamic_or_shared.html | 4 +
libstdc++-v3/doc/xml/manual/using.xml | 37 +-
libstdc++-v3/include/std/stacktrace | 144 +---
libstdc++-v3/scripts/testsuite_flags.in | 8 +-
libstdc++-v3/src/Makefile.am | 4 +-
libstdc++-v3/src/Makefile.in | 7 +-
libstdc++-v3/src/c++20/Makefile.am | 2 +-
libstdc++-v3/src/c++20/Makefile.in | 2 +-
libstdc++-v3/src/c++23/Makefile.am | 109 +++
libstdc++-v3/src/c++23/Makefile.in | 747 ++++++++++++++++++
libstdc++-v3/src/c++23/stacktrace.cc | 171 ++++
libstdc++-v3/src/experimental/Makefile.am | 20 +
libstdc++-v3/src/experimental/Makefile.in | 15 +-
libstdc++-v3/src/libbacktrace/Makefile.am | 3 +-
libstdc++-v3/src/libbacktrace/Makefile.in | 88 +--
.../19_diagnostics/stacktrace/current.cc | 2 +-
.../19_diagnostics/stacktrace/entry.cc | 2 +-
.../19_diagnostics/stacktrace/stacktrace.cc | 2 +-
.../vector/debug/assign4_backtrace_neg.cc | 2 +-
22 files changed, 1185 insertions(+), 228 deletions(-)
create mode 100644 libstdc++-v3/src/c++23/Makefile.am
create mode 100644 libstdc++-v3/src/c++23/Makefile.in
create mode 100644 libstdc++-v3/src/c++23/stacktrace.cc
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index fcf79503265..34faa3c049f 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -49,7 +49,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [
# Keep these sync'd with the list in Makefile.am. The first provides an
# expandable list at autoconf time; the second provides an expandable list
# (i.e., shell variable) at configure time.
- m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11
src/c++17 src/c++20 src/filesystem src/libbacktrace src/experimental doc po
testsuite python])
+ m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11
src/c++17 src/c++20 src/c++23 src/filesystem src/libbacktrace src/experimental
doc po testsuite python])
SUBDIRS='glibcxx_SUBDIRS'
# These need to be absolute paths, yet at the same time need to
diff --git a/libstdc++-v3/doc/xml/manual/using.xml
b/libstdc++-v3/doc/xml/manual/using.xml
index 3a507fc1671..7276cad0feb 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -100,30 +100,27 @@
</entry>
</row>
- <row>
- <entry><literal>-lstdc++fs</literal></entry>
- <entry>Linking to <filename class="libraryfile">libstdc++fs</filename>
- is required for use of the Filesystem library extensions in
- <filename
class="headerfile"><experimental/filesystem></filename>.
- </entry>
- </row>
-
<row>
<entry><literal>-lstdc++exp</literal></entry>
- <entry>Linking to <filename class="libraryfile">libstdc++exp</filename>
- is required for use of the C++ Contracts extensions enabled by
- <literal>-fcontracts</literal>.
+ <entry>Linking to <filename class="libraryfile">libstdc++exp.a</filename>
+ is required for use of experimental C++ library features.
+ This currently provides support for the C++23 types defined in the
+ <filename class="headerfile"><stacktrace></filename> header,
+ the Filesystem library extensions defined in the
+ <filename class="headerfile"><experimental/filesystem></filename>
+ header,
+ and the Contracts extensions enabled by <literal>-fcontracts</literal>.
</entry>
</row>
<row>
- <entry><literal>-lstdc++_libbacktrace</literal></entry>
- <entry>Until C++23 support is non-experimental, linking to
- <filename class="libraryfile">libstdc++_libbacktrace.a</filename>
- is required for use of the C++23 type
- <classname>std::stacktrace</classname>
- and related types in
- <filename class="headerfile"><stacktrace></filename>.
+ <entry><literal>-lstdc++fs</literal></entry>
+ <entry>Linking to <filename class="libraryfile">libstdc++fs.a</filename>
+ is another way to use the Filesystem library extensions defined in the
+ <filename class="headerfile"><experimental/filesystem></filename>
+ header.
+ The <filename class="libraryfile">libstdc++exp.a</filename> library
+ also provides all the symbols contained in this library.
</entry>
</row>
@@ -1710,6 +1707,10 @@ A quick read of the relevant part of the GCC
and link with <option>-lstdc++fs</option>. The library implementation
is incomplete on non-POSIX platforms, specifically Windows is only
partially supported.
+ Since GCC 14, <filename class="libraryfile">libstdc++exp.a</filename>
+ also contains the definitions for this library,
+ so <option>-lstdc++exp</option> can be used instead of
+ <option>-lstdc++fs</option>.
</para>
<para>
diff --git a/libstdc++-v3/include/std/stacktrace
b/libstdc++-v3/include/std/stacktrace
index 07949e70861..358a81b82e5 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -45,43 +45,6 @@
#include <bits/stl_uninitialized.h>
#include <ext/numeric_traits.h>
-struct __glibcxx_backtrace_state;
-struct __glibcxx_backtrace_simple_data;
-
-extern "C"
-{
-__glibcxx_backtrace_state*
-__glibcxx_backtrace_create_state(const char*, int,
- void(*)(void*, const char*, int),
- void*);
-
-int
-__glibcxx_backtrace_simple(__glibcxx_backtrace_state*, int,
- int (*) (void*, __UINTPTR_TYPE__),
- void(*)(void*, const char*, int),
- void*);
-int
-__glibcxx_backtrace_pcinfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__,
- int (*)(void*, __UINTPTR_TYPE__,
- const char*, int, const char*),
- void(*)(void*, const char*, int),
- void*);
-
-int
-__glibcxx_backtrace_syminfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__ addr,
- void (*) (void*, __UINTPTR_TYPE__, const char*,
- __UINTPTR_TYPE__, __UINTPTR_TYPE__),
- void(*)(void*, const char*, int),
- void*);
-}
-
-namespace __cxxabiv1
-{
- extern "C" char*
- __cxa_demangle(const char* __mangled_name, char* __output_buffer,
- size_t* __length, int* __status);
-}
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -156,80 +119,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Allocator> friend class basic_stacktrace;
- static void _S_err_handler(void*, const char*, int) { }
-
- static __glibcxx_backtrace_state*
- _S_init()
- {
- static __glibcxx_backtrace_state* __state
- = __glibcxx_backtrace_create_state(nullptr, 1, _S_err_handler, nullptr);
- return __state;
- }
-
friend ostream&
operator<<(ostream&, const stacktrace_entry&);
+ // Type-erased wrapper for the fields of a stacktrace entry.
+ // This type is independent of which std::string ABI is in use.
+ struct _Info
+ {
+ void* _M_desc;
+ void* _M_file;
+ int* _M_line;
+ void (*_M_set)(void*, const char*);
+
+ _GLIBCXX_DEFAULT_ABI_TAG
+ static void
+ _S_set(void* __dest, const char* __str)
+ { static_cast<string*>(__dest)->assign(__str); }
+
+ _Info(string* __desc, string* __file, int* __line)
+ : _M_desc(__desc), _M_file(__file), _M_line(__line), _M_set(_S_set)
+ { }
+
+ bool
+ _M_populate(native_handle_type);
+
+ void _M_set_file(const char*);
+ void _M_set_desc(const char*);
+ };
+
bool
_M_get_info(string* __desc, string* __file, int* __line) const
{
if (!*this)
return false;
-
- struct _Data
- {
- string* _M_desc;
- string* _M_file;
- int* _M_line;
- } __data = { __desc, __file, __line };
-
- auto __cb = [](void* __data, uintptr_t, const char* __filename,
- int __lineno, const char* __function) -> int {
- auto& __d = *static_cast<_Data*>(__data);
- if (__function && __d._M_desc)
- *__d._M_desc = _S_demangle(__function);
- if (__filename && __d._M_file)
- *__d._M_file = __filename;
- if (__d._M_line)
- *__d._M_line = __lineno;
- return __function != nullptr;
- };
- const auto __state = _S_init();
- if (::__glibcxx_backtrace_pcinfo(__state, _M_pc, +__cb, _S_err_handler,
- &__data))
- return true;
- if (__desc && __desc->empty())
- {
- auto __cb2 = [](void* __data, uintptr_t, const char* __symname,
- uintptr_t, uintptr_t) {
- if (__symname)
- *static_cast<_Data*>(__data)->_M_desc = _S_demangle(__symname);
- };
- if (::__glibcxx_backtrace_syminfo(__state, _M_pc, +__cb2,
- _S_err_handler, &__data))
- return true;
- }
- return false;
+ return _Info(__desc, __file, __line)._M_populate(_M_pc);
}
+ };
- static string
- _S_demangle(const char* __name)
- {
- string __s;
- int __status;
- char* __str = __cxxabiv1::__cxa_demangle(__name, nullptr, nullptr,
- &__status);
- if (__status == 0)
- __s = __str;
- else
- __s = __name;
- __builtin_free(__str);
- return __s;
- }
+ class __stacktrace_impl
+ {
+ protected:
+ static int _S_current(int (*) (void*, __UINTPTR_TYPE__), void*, int = 0);
};
// [stacktrace.basic], class template basic_stacktrace
template<typename _Allocator>
class basic_stacktrace
+ : private __stacktrace_impl
{
using _AllocTraits = allocator_traits<_Allocator>;
using uintptr_t = __UINTPTR_TYPE__;
@@ -256,10 +192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
basic_stacktrace __ret(__alloc);
if (auto __cb = __ret._M_prepare()) [[likely]]
{
- auto __state = stacktrace_entry::_S_init();
- if (__glibcxx_backtrace_simple(__state, 1, __cb,
- stacktrace_entry::_S_err_handler,
- std::__addressof(__ret)))
+ if (_S_current(__cb, std::__addressof(__ret)))
__ret._M_clear();
}
return __ret;
@@ -275,10 +208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __ret;
if (auto __cb = __ret._M_prepare()) [[likely]]
{
- auto __state = stacktrace_entry::_S_init();
- if (__glibcxx_backtrace_simple(__state, __skip + 1, __cb,
- stacktrace_entry::_S_err_handler,
- std::__addressof(__ret)))
+ if (_S_current(__cb, std::__addressof(__ret), __skip))
__ret._M_clear();
}
@@ -299,11 +229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __ret;
if (auto __cb = __ret._M_prepare(__max_depth)) [[likely]]
{
- auto __state = stacktrace_entry::_S_init();
- int __err = __glibcxx_backtrace_simple(__state, __skip + 1, __cb,
-
stacktrace_entry::_S_err_handler,
- std::__addressof(__ret));
- if (__err < 0)
+ if (_S_current(__cb, std::__addressof(__ret), __skip) < 0)
__ret._M_clear();
else if (__ret.size() > __max_depth)
{
diff --git a/libstdc++-v3/scripts/testsuite_flags.in
b/libstdc++-v3/scripts/testsuite_flags.in
index 18748f0f9ce..8bf4918287a 100755
--- a/libstdc++-v3/scripts/testsuite_flags.in
+++ b/libstdc++-v3/scripts/testsuite_flags.in
@@ -78,14 +78,14 @@ case ${query} in
;;
--cxxldflags)
FS_LDFLAGS=
- BT_LDFLAGS=
+ EXP_LDFLAGS=
if [ -d ${BUILD_DIR}/src/filesystem/.libs ]; then
FS_LDFLAGS=-L${BUILD_DIR}/src/filesystem/.libs
fi
- if [ -d ${BUILD_DIR}/src/libbacktrace/.libs ]; then
- BT_LDFLAGS=-L${BUILD_DIR}/src/libbacktrace/.libs
+ if [ -d ${BUILD_DIR}/src/experimental/.libs ]; then
+ EXP_LDFLAGS=-L${BUILD_DIR}/src/experimental/.libs
fi
- SECTIONLDFLAGS="@SECTION_LDFLAGS@ @LIBICONV@ $FS_LDFLAGS $BT_LDFLAGS"
+ SECTIONLDFLAGS="@SECTION_LDFLAGS@ @LIBICONV@ $FS_LDFLAGS $EXP_LDFLAGS"
echo ${SECTIONLDFLAGS}
;;
*)
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..32de5304122 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -43,7 +43,8 @@ experimental_dir =
endif
## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
-SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir)
$(experimental_dir)
+SUBDIRS = c++98 c++11 c++17 c++20 c++23 \
+ $(filesystem_dir) $(backtrace_dir) $(experimental_dir)
# Cross compiler support.
if VTV_CYGMIN
@@ -75,6 +76,7 @@ vpath % $(top_srcdir)/src/c++98
vpath % $(top_srcdir)/src/c++11
vpath % $(top_srcdir)/src/c++17
vpath % $(top_srcdir)/src/c++20
+vpath % $(top_srcdir)/src/c++23
if ENABLE_FILESYSTEM_TS
vpath % $(top_srcdir)/src/filesystem
endif
diff --git a/libstdc++-v3/src/c++20/Makefile.am
b/libstdc++-v3/src/c++20/Makefile.am
index 0bc8a7b832a..e947855e6ae 100644
--- a/libstdc++-v3/src/c++20/Makefile.am
+++ b/libstdc++-v3/src/c++20/Makefile.am
@@ -22,7 +22,7 @@
include $(top_srcdir)/fragment.am
-# Convenience library for C++17 runtime.
+# Convenience library for C++20 runtime.
noinst_LTLIBRARIES = libc++20convenience.la
headers =
diff --git a/libstdc++-v3/src/c++23/Makefile.am
b/libstdc++-v3/src/c++23/Makefile.am
new file mode 100644
index 00000000000..da988c352f8
--- /dev/null
+++ b/libstdc++-v3/src/c++23/Makefile.am
@@ -0,0 +1,109 @@
+## Makefile for the C++23 sources of the GNU C++ Standard library.
+##
+## Copyright (C) 1997-2023 Free Software Foundation, Inc.
+##
+## This file is part of the libstdc++ version 3 distribution.
+## Process this file with automake to produce Makefile.in.
+
+## 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
+## terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 3, or (at your option)
+## any later version.
+
+## This library 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 this library; see the file COPYING3. If not see
+## <http://www.gnu.org/licenses/>.
+
+include $(top_srcdir)/fragment.am
+
+# Convenience library for C++23 runtime.
+noinst_LTLIBRARIES = libc++23convenience.la
+
+headers =
+
+if ENABLE_EXTERN_TEMPLATE
+# XTEMPLATE_FLAGS = -fno-implicit-templates
+inst_sources =
+else
+# XTEMPLATE_FLAGS =
+inst_sources =
+endif
+
+sources = stacktrace.cc
+
+vpath % $(top_srcdir)/src/c++23
+
+
+if GLIBCXX_HOSTED
+libc__23convenience_la_SOURCES = $(sources) $(inst_sources)
+else
+libc__23convenience_la_SOURCES =
+endif
+
+# AM_CXXFLAGS needs to be in each subdirectory so that it can be
+# modified in a per-library or per-sub-library way. Need to manually
+# set this option because CONFIG_CXXFLAGS has to be after
+# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
+# as the occasion calls for it.
+AM_CXXFLAGS = \
+ -std=gnu++23 \
+ $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
+ -fimplicit-templates
+
+AM_MAKEFLAGS = \
+ "gxx_include_dir=$(gxx_include_dir)"
+
+# Libtool notes
+
+# 1) In general, libtool expects an argument such as `--tag=CXX' when
+# using the C++ compiler, because that will enable the settings
+# detected when C++ support was being configured. However, when no
+# such flag is given in the command line, libtool attempts to figure
+# it out by matching the compiler name in each configuration section
+# against a prefix of the command line. The problem is that, if the
+# compiler name and its initial flags stored in the libtool
+# configuration file don't match those in the command line, libtool
+# can't decide which configuration to use, and it gives up. The
+# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
+# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
+# attempt to infer which configuration to use.
+#
+# The second tag argument, `--tag disable-shared` means that libtool
+# only compiles each source once, for static objects. In actuality,
+# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
+# the libtool command that is used create the object, which is
+# suitable for shared libraries. The `--tag disable-shared` must be
+# placed after --tag CXX lest things CXX undo the affect of
+# disable-shared.
+
+# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
+# last. (That way, things like -O2 passed down from the toplevel can
+# be overridden by --enable-debug.)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(EXTRA_CXX_FLAGS)
+
+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+
+# 3) We'd have a problem when building the shared libstdc++ object if
+# the rules automake generates would be used. We cannot allow g++ to
+# be used since this would add -lstdc++ to the link line which of
+# course is problematic at this point. So, we get the top-level
+# directory to configure libstdc++-v3 to use gcc as the C++
+# compilation driver.
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/src/c++23/stacktrace.cc
b/libstdc++-v3/src/c++23/stacktrace.cc
new file mode 100644
index 00000000000..10cfa44e4f5
--- /dev/null
+++ b/libstdc++-v3/src/c++23/stacktrace.cc
@@ -0,0 +1,171 @@
+// Implementation of <stacktrace> -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3.
+
+// This library 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <stacktrace>
+#include <cstdlib>
+
+#ifdef __cpp_lib_stacktrace // C++ >= 23 && hosted && HAVE_STACKTRACE
+struct __glibcxx_backtrace_state;
+
+extern "C"
+{
+__glibcxx_backtrace_state*
+__glibcxx_backtrace_create_state(const char*, int,
+ void(*)(void*, const char*, int),
+ void*);
+
+int
+__glibcxx_backtrace_simple(__glibcxx_backtrace_state*, int,
+ int (*) (void*, __UINTPTR_TYPE__),
+ void(*)(void*, const char*, int),
+ void*);
+int
+__glibcxx_backtrace_pcinfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__,
+ int (*)(void*, __UINTPTR_TYPE__,
+ const char*, int, const char*),
+ void(*)(void*, const char*, int),
+ void*);
+
+int
+__glibcxx_backtrace_syminfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__ addr,
+ void (*) (void*, __UINTPTR_TYPE__, const char*,
+ __UINTPTR_TYPE__, __UINTPTR_TYPE__),
+ void(*)(void*, const char*, int),
+ void*);
+}
+
+namespace __cxxabiv1
+{
+ extern "C" char*
+ __cxa_demangle(const char* mangled_name, char* output_buffer, size_t* length,
+ int* status);
+}
+
+namespace std
+{
+namespace
+{
+ char*
+ demangle(const char* name)
+ {
+ int status;
+ char* str = __cxxabiv1::__cxa_demangle(name, nullptr, nullptr, &status);
+ if (status == 0)
+ return str;
+ else
+ {
+ std::free(str);
+ return nullptr;
+ }
+ }
+
+ void
+ err_handler(void*, const char*, int)
+ { }
+
+ __glibcxx_backtrace_state*
+ init()
+ {
+#if __GTHREADS && ! defined(__cpp_threadsafe_static_init)
+# warning "std::stacktrace initialization will not be thread-safe"
+#endif
+ static __glibcxx_backtrace_state* state
+ = __glibcxx_backtrace_create_state(nullptr, 1, err_handler, nullptr);
+ return state;
+ }
+}
+
+void
+stacktrace_entry::_Info::_M_set_file(const char* filename)
+{
+ if (filename && _M_file)
+ _M_set(_M_file, filename);
+}
+
+void
+stacktrace_entry::_Info::_M_set_desc(const char* function)
+{
+ if (function && _M_desc)
+ {
+ if (char* s = demangle(function))
+ {
+ _M_set(_M_desc, s);
+ std::free(s);
+ }
+ else
+ _M_set(_M_desc, function);
+ }
+}
+
+#pragma GCC diagnostic push
+// The closure types below don't escape so we don't care about their mangling.
+#pragma GCC diagnostic ignored "-Wabi"
+bool
+stacktrace_entry::_Info::_M_populate(native_handle_type pc)
+{
+ auto cb = [](void* self, uintptr_t, const char* filename, int lineno,
+ const char* function) -> int
+ {
+ auto& info = *static_cast<_Info*>(self);
+ info._M_set_desc(function);
+ info._M_set_file(filename);
+ if (info._M_line)
+ *info._M_line = lineno;
+ return function != nullptr;
+ };
+ const auto state = init();
+ if (::__glibcxx_backtrace_pcinfo(state, pc, +cb, err_handler, this))
+ return true;
+
+ // If we get here then backtrace_pcinfo did not give us a function name.
+ // If the caller wanted a function name, try again using backtrace_syminfo.
+ if (_M_desc)
+ {
+ auto cb2 = [](void* self, uintptr_t, const char* symname,
+ uintptr_t, uintptr_t)
+ {
+ static_cast<_Info*>(self)->_M_set_desc(symname);
+ };
+ if (::__glibcxx_backtrace_syminfo(state, pc, +cb2, err_handler, this))
+ return true;
+ }
+ return false;
+}
+#pragma GCC diagnostic pop
+
+// Ensure no tail-call optimization, so that this frame isn't reused for the
+// backtrace_simple call, so that the number of frames to skip doesn't vary.
+[[gnu::optimize("no-optimize-sibling-calls")]]
+int
+__stacktrace_impl::_S_current(int (*cb) (void*, __UINTPTR_TYPE__), void* obj,
+ int skip)
+{
+ const auto state = init();
+ // skip+2 because we don't want this function or its caller to be included.
+ int r = ::__glibcxx_backtrace_simple(state, skip + 2, cb, err_handler, obj);
+ // Could also use this to prevent tail-call optim: __asm ("" : "+g" (r));
+ return r;
+}
+
+}
+#endif
diff --git a/libstdc++-v3/src/experimental/Makefile.am
b/libstdc++-v3/src/experimental/Makefile.am
index 3b962e7d804..a61465f4eaf 100644
--- a/libstdc++-v3/src/experimental/Makefile.am
+++ b/libstdc++-v3/src/experimental/Makefile.am
@@ -24,6 +24,18 @@ include $(top_srcdir)/fragment.am
toolexeclib_LTLIBRARIES = libstdc++exp.la
+if ENABLE_FILESYSTEM_TS
+filesystem_lib = $(top_builddir)/src/filesystem/libstdc++fs.la
+else
+filesystem_lib =
+endif
+
+if ENABLE_BACKTRACE
+backtrace_lib = $(top_builddir)/src/libbacktrace/libstdc++_libbacktrace.la
+else
+backtrace_lib =
+endif
+
headers =
sources = \
@@ -33,6 +45,14 @@ sources = \
libstdc__exp_la_SOURCES = $(sources)
+libstdc__exp_la_LIBADD = \
+ $(top_builddir)/src/c++23/libc++23convenience.la \
+ $(filesystem_lib) $(backtrace_lib)
+
+libstdc__exp_la_DEPENDENCIES = \
+ $(top_builddir)/src/c++23/libc++23convenience.la \
+ $(filesystem_lib) $(backtrace_lib)
+
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
diff --git a/libstdc++-v3/src/libbacktrace/Makefile.am
b/libstdc++-v3/src/libbacktrace/Makefile.am
index 27c1ea570e0..492d3b6e952 100644
--- a/libstdc++-v3/src/libbacktrace/Makefile.am
+++ b/libstdc++-v3/src/libbacktrace/Makefile.am
@@ -31,7 +31,8 @@
include $(top_srcdir)/fragment.am
-toolexeclib_LTLIBRARIES = libstdc++_libbacktrace.la
+# Convenience library for C++23 runtime.
+noinst_LTLIBRARIES = libstdc++_libbacktrace.la
ACLOCAL_AMFLAGS = -I ../.. -I ../../config
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
index 184e23b460e..f6c860fc7a4 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
+// { dg-options "-std=gnu++23 -lstdc++exp" }
// { dg-do run { target c++23 } }
// { dg-require-effective-target stacktrace }
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
index a222c425b20..f0406953d03 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
+// { dg-options "-std=gnu++23 -lstdc++exp" }
// { dg-do run { target c++23 } }
// { dg-require-effective-target stacktrace }
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 8dfdf4739be..0a358b7b8ff 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
+// { dg-options "-std=gnu++23 -lstdc++exp" }
// { dg-do run { target c++23 } }
// { dg-require-effective-target stacktrace }
diff --git
a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
index 520788d5cb7..43a82fb1201 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
@@ -1,5 +1,5 @@
// { dg-do run { xfail *-*-* } }
-// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" }
+// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++exp" }
// { dg-require-effective-target stacktrace }
#include <debug/vector>
--
2.41.0