[PATCH] libstdc++, v2: Implement C++26 P3378R2 - constexpr exception types [PR121114]
Jakub Jelinek
jakub@redhat.com
Wed Aug 13 10:55:40 GMT 2025
Hi!
Here is an updated version of the
https://gcc.gnu.org/pipermail/libstdc++/2025-July/062597.html
patch, which removes the __throw_format_error forward declaration
which apparently wasn't needed for anything as all __throw_format_error
users were either in <format> or included <format> before the uses,
reverts the
https://gcc.gnu.org/pipermail/libstdc++/2025-July/062598.html
patch and makes sure __throw_* functions (only those for exception types
which the P3378R2 or P3068R5 papers made constexpr usable) are constexpr
for C++26 constexpr exceptions.
The patch does that by turning bits/functexcept.h into a multiple inclusion
header with __glibcxx_exc_want_* macros requesting particular __throw_*
functions or constexpr exception classes.
The most problematic was <string> vs. <string_view> vs. <stdexcept>.
<string> and headers it includes use various __throw_* functions, including
those for <stdexcept> provided classes, but the
https://eel.is/c++draft/std.exceptions#general
classes all have constexpr ctors with const std::string& argument, for
those even just a forward declaration of std::string is not good enough
and so need to be defined after most of <string> is included. Furthermore
<string> includes indirectly <string_view>, but that header can be included
outside of it as well and also needs __throw_* functions for <stdexcept>
provided classes. So in the string case for C++26 constexpr exceptions
I need to declare the constexpr __throw_* functions early but ensure at the
end of <string> (or <string_view> if not included from <string>)
bits/functexcept.h provides definitions for those constexpr functions.
And can't include <stdexcept> from <string> because <stdexcept> includes
<string>, so that would be circular and break again, that is why I've moved
the actual class definitions into bits/stdexcept.h.
Bootstrapped/regtested on x86_64-linux and i686-linux.
Additionally tested with the bits/extc++.h header with
bits/stdtr1c++.h and bits/stdc++.h headers manually included and the whole
content manually changed each
#include <whatever>
to
#if NNN == __LINE__
#include <whatever>
#endif
and a script including such header for all of -std=c++{98,11,14,17,20,23,26}
and all of NNN from 1 to number of lines in that file, i.e. trying to make
sure one can include each of those headers on its own and compile that
for the language versions bits/extc++.h includes them all together.
Or if the multiple inclusion bits/functexcept.h header is too costly, we
could instead split it into multiple headers, each with normal header
guards:
1) bits/functexcept.h would stay for the __throw_* functions which are (at
least for now) never constexpr (the <ios>, <system_error>, <future>
and <functional> std::exception derived classes)
2) bits/exception_{throw,except}.h for __throw_bad_exception and
std::bad_exception (where <exception> would include <bits/exception_except.h>
and <bits/exception_throw.h> as well for the C++26 constexpr exceptions case)
3) similarly for the <new> and <typeinfo> cases,
bits/new_{throw,except}.h and bits/typeinfo_{throw,except}.h (or
_functexcept.h vs. _except.h ?)
4) for the most complicated <stdexcept> stuff, we'd probably need in
addition to bits/stdexcept.h one header for the __throw_logic_error etc.
forward declarations, one header for the __throw_logic_error etc.
definitions and perhaps one header without header guards which will
depending on __glibcxx_exc_in_string include one or the other
Thoughts on this?
BTW, the g++.dg/tree-ssa/*.C failures without the tweaks in the patch
are caused by constexpr dtors of std::bad_alloc and
std::bad_array_new_length, as we don't (yet?) have any hacks to pretend
those classes don't have a key method defined, the vtable for those is
emitted whenever <vector> etc. is included for C++26 and the deleting
dtors of those use operator delete which the tests scan for this not
occurring. I think an attribute not to treat the class as having a key
method would be nice for that (though easy to misuse, one would need to
arrange for some TU not to have that attribute; easy to do for libstdc++
when we define those classes in C++ < 26 compiled TUs where the attribute
wouldn't be present).
2025-08-13 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/121114
libstdc++-v3/
* include/bits/version.def: Implement C++26 P3378R2 - constexpr
exception types.
(constexpr_exceptions): Change value from 1 to 202502, remove
no_stdname and TODO comments.
* include/bits/version.h: Regenerate.
* src/c++11/cow-stdexcept.cc (__cow_string(const char*)): New
ctor.
(__cow_string::c_str()): New method.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.35): Export 8 __cow_string
symbols.
* include/std/stdexcept: Include bits/stdexcept.h and move everything
after <string> include into ...
* include/bits/stdexcept.h: ... this new header.
(__cow_constexpr_string): New class if
__cpp_lib_constexpr_exceptions >= 202502L.
(__cow_string): In that case typedef to __cow_constexpr_string.
(logic_error, domain_error, invalid_argument, length_error,
out_of_range, runtime_error, range_error, overflow_error,
underflow_error): If __cpp_lib_constexpr_exceptions >= 202502L
make all cdtors and methods constexpr.
* include/std/optional (__glibcxx_want_constexpr_exceptions): Define
before including bits/version.h.
(bad_optional_access::what): Make constexpr for
__cpp_lib_constexpr_exceptions >= 202502L.
(__throw_bad_optional_access): Likewise.
* include/std/expected (__glibcxx_want_constexpr_exceptions): Define
before including bits/version.h.
(bad_expected_access): Make cdtors and all methods constexpr for
__cpp_lib_constexpr_exceptions >= 202502L.
* include/std/format (__glibcxx_want_constexpr_exceptions): Define
before including bits/version.h.
(_GLIBCXX_CONSTEXPR_FORMAT_ERROR): Define and undef later.
(format_error): Use _GLIBCXX_CONSTEXPR_FORMAT_ERROR on ctors.
* include/std/variant (__glibcxx_want_constexpr_exceptions): Define
before including bits/version.h.
(_GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS): Define and undef later.
(bad_variant_access): Use it on ctors and what() method.
(__throw_bad_variant_access): Use it here too.
* testsuite/18_support/exception/version.cc: Adjust expected
__cpp_lib_constexpr_exceptions value.
* testsuite/19_diagnostics/runtime_error/constexpr.cc: New test.
* testsuite/19_diagnostics/headers/stdexcept/version.cc: New test.
* testsuite/19_diagnostics/logic_error/constexpr.cc: New test.
* testsuite/20_util/expected/observers.cc (test_value_throw): Change
return type to bool from void, return true at the end, add test
to dereference what() first character. Make it constexpr for
__cpp_lib_constexpr_exceptions >= 202502L and add static_assert.
* testsuite/20_util/expected/version.cc: Add tests for
__cpp_lib_constexpr_exceptions value.
* testsuite/20_util/variant/constexpr.cc: For
__cpp_lib_constexpr_exceptions >= 202502L include <string>.
(test_get): New function if __cpp_lib_constexpr_exceptions >= 202502L,
assert calling it is true.
* testsuite/20_util/variant/version.cc: Add tests for
__cpp_lib_constexpr_exceptions value.
* testsuite/20_util/optional/constexpr/observers/3.cc: Include
testsuite_hooks.h.
(eat, test01): New functions. Assert test01() is true.
* testsuite/20_util/optional/version.cc: Add tests for
__cpp_lib_constexpr_exceptions value.
* include/std/future: Add #include <bits/functexcept.h>.
(__glibcxx_exc_want_throw_future_error): Define it before including
that header.
* include/std/shared_mutex (__glibcxx_exc_want_throw_bad_alloc,
__glibcxx_exc_want_throw_system_error): Define before including
bits/functexcept.h.
* include/std/flat_map (__glibcxx_exc_want_throw_out_of_range):
Likewise.
* include/std/syncstream: Remove bits/functexcept.h include.
* include/std/mutex (__glibcxx_exc_want_throw_system_error): Define
before including bits/functexcept.h.
* include/std/flat_set: Remove bits/functexcept.h include.
* include/std/bitset (__glibcxx_exc_want_throw_overflow_error,
__glibcxx_exc_want_throw_out_of_range,
__glibcxx_exc_want_throw_logic_error,
__glibcxx_exc_want_throw_invalid_argument): Define before including
bits/functexcept.h.
* include/std/print (__glibcxx_exc_want_throw_system_error): Likewise.
* include/std/string_view: Don't include bits/functexcept.h early if
__glibcxx_exc_in_string is defined and include it at the end of
the header again if __glibcxx_exc_in_string is 2 and C++26 constexpr
exceptions are enabled.
(__glibcxx_exc_in_string, __glibcxx_exc_want_throw_out_of_range):
Define if __glibcxx_exc_in_string wasn't defined before including
bits/functexcept.h.
* include/std/array (__glibcxx_exc_want_throw_out_of_range): Define
before including bits/functexcept.h.
* include/std/inplace_vector: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_out_of_range): Define before including
bits/functexcept.h.
* include/std/string: Include bits/stdexcept.h and bits/functexcept.h
after bits/basic_string.tcc include if C++26 constexpr exceptions
are enabled.
(__glibcxx_exc_in_string): Define early to 1, undefine at the end.
(__glibcxx_exc_want_throw_length_error,
__glibcxx_exc_want_throw_logic_error,
__glibcxx_exc_want_throw_out_of_range): Define before including
bits/functexcept.h.
* include/std/deque: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_length_error): Define before including
bits/functexcept.h.
* include/bits/new_allocator.h (__glibcxx_exc_want_throw_bad_alloc,
__glibcxx_exc_want_throw_bad_array_new_length): Likewise.
* include/bits/stl_algobase.h: Remove bits/functexcept.h include.
* include/bits/stl_vector.h (__glibcxx_exc_want_throw_out_of_range,
__glibcxx_exc_want_throw_length_error): Define before including
bits/functexcept.h.
* include/bits/memory_resource.h
(__glibcxx_exc_want_throw_bad_array_new_length): Likewise.
* include/bits/std_mutex.h (__glibcxx_exc_want_throw_system_error):
Likewise.
* include/bits/functexcept.h: Remove header guards, turn into a header
for multiple inclusion providing content depending on
__glibcxx_exc_want* macros defined before including it, undefine all
those macros afterwards. Include bits/exception.h and/or string if
needed. For C++26 constexpr exceptions define __throw_* functions as
constexpr.
(std::bad_exception, std::bad_alloc, std::bad_array_new_length,
std::bad_cast, std::bad_typeid): Move class definitions here and guard
them on __glibcxx_exc_want* macros.
* include/bits/stl_map.h (__glibcxx_exc_want_throw_out_of_range):
Define before including bits/functexcept.h.
* include/bits/locale_classes.h: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_bad_cast,
__glibcxx_exc_want_throw_system_error): Define before including
bits/functexcept.h.
* include/bits/hashtable_policy.h: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_out_of_range): Define before including
bits/functexcept.h.
* include/bits/std_function.h
(__glibcxx_exc_want_throw_bad_function_call): Likewise.
* include/bits/formatfwd.h (std::__throw_format_error): Remove
declaration.
* include/bits/specfun.h: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_domain_error,
__glibcxx_exc_want_throw_runtime_error): Define before including
bits/functexcept.h.
* include/bits/basic_ios.h: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_bad_cast,
__glibcxx_exc_want_throw_ios_failure): Define before including
bits/functexcept.h.
* include/bits/std_thread.h (__glibcxx_exc_want_throw_system_error):
Likewise.
* include/tr1/cmath: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_domain_error,
__glibcxx_exc_want_throw_runtime_error): Define before including
bits/functexcept.h.
* include/tr1/memory: Remove bits/functexcept.h include.
* include/tr1/array: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_out_of_range): Define before including
bits/functexcept.h.
* include/ext/vstring_util.h (__glibcxx_exc_want_throw_length_error,
__glibcxx_exc_want_throw_logic_error,
__glibcxx_exc_want_throw_out_of_range): Likewise.
* include/ext/bitmap_allocator.h (__glibcxx_exc_want_throw_bad_alloc):
Likewise.
* include/ext/mt_allocator.h (__glibcxx_exc_want_throw_bad_alloc):
Likewise.
* include/ext/malloc_allocator.h (__glibcxx_exc_want_throw_bad_alloc,
__glibcxx_exc_want_throw_bad_array_new_length): Likewise.
* include/ext/debug_allocator.h
(__glibcxx_exc_want_throw_runtime_error): Likewise.
* include/ext/concurrence.h: Include bits/exception_defines.h instead
of bits/functexcept.h.
* include/ext/throw_allocator.h (__glibcxx_exc_want_throw_logic_error,
__glibcxx_exc_want_throw_out_of_range,
__glibcxx_exc_want_throw_bad_alloc): Define before including
bits/functexcept.h.
* include/ext/string_conversions.h
(__glibcxx_exc_want_throw_invalid_argument,
__glibcxx_exc_want_throw_out_of_range): Likewise.
* include/ext/pool_allocator.h (__glibcxx_exc_want_throw_bad_alloc):
Likewise.
* include/ext/ropeimpl.h (__glibcxx_exc_want_throw_length_error):
Likewise.
* include/tr2/dynamic_bitset (__glibcxx_exc_want_throw_out_of_range,
__glibcxx_exc_want_throw_overflow_error,
__glibcxx_exc_want_throw_invalid_argument): Likewise.
* include/experimental/optional: Include bits/exception_defines.h
instead of bits/functexcept.h.
* include/Makefile.am (bits_headers): Add ${bits_srcdir}/stdexcept.h.
* include/Makefile.in: Regenerate.
* src/c++20/atomic.cc (__glibcxx_exc_want_throw_all): Define before
including bits/functexcept.h.
* src/c++17/floating_from_chars.cc (__glibcxx_exc_want_throw_all):
Likewise.
* src/c++11/system_error.cc (__glibcxx_exc_want_throw_all): Likewise.
* src/c++11/regex.cc (__glibcxx_exc_want_throw_all): Likewise.
* src/c++11/cxx11-ios_failure.cc (__glibcxx_exc_want_throw_all):
Likewise.
* src/c++11/functexcept.cc (__glibcxx_exc_want_throw_all): Likewise.
* src/c++11/snprintf_lite.cc (__glibcxx_exc_want_throw_all): Likewise.
* src/c++11/future.cc (__glibcxx_exc_want_throw_all): Likewise.
* src/c++11/thread.cc: Include bits/functexcept.h.
(__glibcxx_exc_want_throw_system_error): Define before including
bits/functexcept.h.
* src/c++11/functional.cc (__glibcxx_exc_want_throw_all): Likewise.
* testsuite/util/testsuite_shared.cc
(__glibcxx_exc_want_throw_bad_exception): Likewise.
* testsuite/util/testsuite_hooks.h
(__glibcxx_exc_want_throw_runtime_error): Likewise.
* testsuite/util/io/verified_cmd_line_input.cc: Include
bits/exception_defines.h instead of bits/functexcept.h.
* testsuite/20_util/allocator/105975.cc: Expect different diagnostics
for C++26.
* testsuite/23_containers/array/tuple_interface/get_neg.cc: Except
diagnostics one line later than before.
* testsuite/23_containers/inplace_vector/access/capacity.cc: Remove
#error, guard if consteval { return; } with
#ifndef __cpp_lib_constexpr_exceptions.
* testsuite/23_containers/inplace_vector/access/elem.cc: Likewise.
* testsuite/23_containers/inplace_vector/cons/1.cc: Likewise.
* testsuite/23_containers/inplace_vector/cons/from_range.cc: Likewise.
* testsuite/23_containers/inplace_vector/modifiers/single_insert.cc:
Likewise.
* testsuite/23_containers/inplace_vector/modifiers/assign.cc:
Likewise.
* testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
Likewise.
* libsupc++/exception: Include bits/functexcept.h.
(__glibcxx_exc_want_exception): Define before including
bits/functexcept.h.
(std::bad_exception): Move defintion to bits/functexcept.h.
* libsupc++/new: Include bits/functexcept.h.
(__glibcxx_exc_want_new): Define before including
bits/functexcept.h.
(std::bad_alloc, std::bad_array_new_length): Move defintion to
bits/functexcept.h.
* libsupc++/typeinfo: Include bits/functexcept.h.
(__glibcxx_exc_want_typeinfo): Define before including
bits/functexcept.h.
(std::bad_cast, std::bad_typeid): Move defintion to bits/functexcept.h.
libgomp/
* omp.h.in (__glibcxx_exc_want_throw_bad_alloc,
__glibcxx_exc_want_throw_bad_array_new_length): Define before
including bits/functexcept.h.
gcc/testsuite/
* g++.dg/tree-ssa/pr110819.C: Guard scan-tree-dump-not delete on
c++23_down and add comment explaining why C++26 fails that.
* g++.dg/tree-ssa/pr96945.C: Likewise.
* g++.dg/tree-ssa/pr109442.C: Likewise.
* g++.dg/tree-ssa/pr116868.C: Likewise.
* g++.dg/tree-ssa/pr58483.C: Likewise.
--- libstdc++-v3/include/bits/version.def.jj 2025-08-12 18:31:42.165614412 +0200
+++ libstdc++-v3/include/bits/version.def 2025-08-12 18:32:56.415661472 +0200
@@ -2060,10 +2060,8 @@ ftms = {
ftms = {
name = constexpr_exceptions;
- // TODO Remove when PR121114 is resolved
- no_stdname = true;
values = {
- v = 1; // TODO 202411;
+ v = 202502;
cxxmin = 26;
extra_cond = "__cpp_constexpr_exceptions >= 202411L";
};
--- libstdc++-v3/include/bits/version.h.jj 2025-08-12 18:31:42.166614399 +0200
+++ libstdc++-v3/include/bits/version.h 2025-08-12 18:32:56.417661447 +0200
@@ -2311,8 +2311,9 @@
#if !defined(__cpp_lib_constexpr_exceptions)
# if (__cplusplus > 202302L) && (__cpp_constexpr_exceptions >= 202411L)
-# define __glibcxx_constexpr_exceptions 1L
+# define __glibcxx_constexpr_exceptions 202502L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constexpr_exceptions)
+# define __cpp_lib_constexpr_exceptions 202502L
# endif
# endif
#endif /* !defined(__cpp_lib_constexpr_exceptions) && defined(__glibcxx_want_constexpr_exceptions) */
--- libstdc++-v3/src/c++11/cow-stdexcept.cc.jj 2025-08-12 18:31:42.189614104 +0200
+++ libstdc++-v3/src/c++11/cow-stdexcept.cc 2025-08-12 18:32:56.421661395 +0200
@@ -126,18 +126,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cow_string();
__cow_string(const std::string& s);
+ __cow_string(const char*);
__cow_string(const char*, size_t n);
__cow_string(const __cow_string&) noexcept;
__cow_string& operator=(const __cow_string&) noexcept;
~__cow_string();
__cow_string(__cow_string&&) noexcept;
__cow_string& operator=(__cow_string&&) noexcept;
+ const char* c_str() const noexcept;
};
__cow_string::__cow_string() : _M_str() { }
__cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+ __cow_string::__cow_string(const char* s) : _M_str(s) { }
+
__cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
__cow_string::__cow_string(const __cow_string& s) noexcept
@@ -162,6 +166,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+ const char*
+ __cow_string::c_str() const noexcept
+ {
+ return _M_str.c_str();
+ }
+
static_assert(sizeof(__cow_string) == sizeof(std::string),
"sizeof(std::string) has changed");
static_assert(alignof(__cow_string) == alignof(std::string),
--- libstdc++-v3/config/abi/pre/gnu.ver.jj 2025-08-12 18:31:42.149614617 +0200
+++ libstdc++-v3/config/abi/pre/gnu.ver 2025-08-12 18:32:56.408661562 +0200
@@ -2569,6 +2569,16 @@ GLIBCXX_3.4.35 {
_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPKNS_30_Safe_unordered_container_baseEb;
_ZNK11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv;
_ZNK11__gnu_debug30_Safe_unordered_container_base7_M_swapERKS0_;
+
+ # std::__cow_string
+ _ZNSt12__cow_stringC2EPKc;
+ _ZNSt12__cow_stringC2EPKc[jmy];
+ _ZNSt12__cow_stringC2ERKS_;
+ _ZNSt12__cow_stringC2EOS_;
+ _ZNSt12__cow_stringD2Ev;
+ _ZNSt12__cow_stringaSERKS_;
+ _ZNSt12__cow_stringaSEOS_;
+ _ZNKSt12__cow_string5c_strEv;
} GLIBCXX_3.4.34;
# Symbols in the support library (libsupc++) have their own tag.
--- libstdc++-v3/include/std/stdexcept.jj 2025-08-12 18:31:42.181614206 +0200
+++ libstdc++-v3/include/std/stdexcept 2025-08-12 18:32:56.410661537 +0200
@@ -39,271 +39,6 @@
#include <exception>
#include <string>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
- // Emulates an old COW string when the new std::string is in use.
- struct __cow_string
- {
- union {
- const char* _M_p;
- char _M_bytes[sizeof(const char*)];
- };
-
- __cow_string();
- __cow_string(const std::string&);
- __cow_string(const char*, size_t);
- __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
- __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
- ~__cow_string();
-#if __cplusplus >= 201103L
- __cow_string(__cow_string&&) noexcept;
- __cow_string& operator=(__cow_string&&) noexcept;
-#endif
- };
-
- typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
- typedef basic_string<char> __cow_string;
-
- // Emulates a new SSO string when the old std::string is in use.
- struct __sso_string
- {
- struct __str
- {
- const char* _M_p;
- size_t _M_string_length;
- char _M_local_buf[16];
- };
-
- union {
- __str _M_s;
- char _M_bytes[sizeof(__str)];
- };
-
- __sso_string() _GLIBCXX_NOTHROW;
- __sso_string(const std::string&);
- __sso_string(const char*, size_t);
- __sso_string(const __sso_string&);
- __sso_string& operator=(const __sso_string&);
- ~__sso_string();
-#if __cplusplus >= 201103L
- __sso_string(__sso_string&&) noexcept;
- __sso_string& operator=(__sso_string&&) noexcept;
-#endif
- };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else // _GLIBCXX_USE_DUAL_ABI
- typedef basic_string<char> __sso_string;
- typedef basic_string<char> __cow_string;
-#endif
-
- /**
- * @addtogroup exceptions
- * @{
- */
-
- /** Logic errors represent problems in the internal logic of a program;
- * in theory, these are preventable, and even detectable before the
- * program runs (e.g., violations of class invariants).
- * @brief One of two subclasses of exception.
- */
- class logic_error : public exception
- {
- __cow_string _M_msg;
-
- public:
- /** Takes a character string describing the error. */
- explicit
- logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-
-#if __cplusplus >= 201103L
- explicit
- logic_error(const char*) _GLIBCXX_TXN_SAFE;
-
- logic_error(logic_error&&) noexcept;
- logic_error& operator=(logic_error&&) noexcept;
-#endif
-
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
- logic_error(const logic_error&) _GLIBCXX_NOTHROW;
- logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
-#elif __cplusplus >= 201103L
- logic_error(const logic_error&) = default;
- logic_error& operator=(const logic_error&) = default;
-#endif
-
- virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
-
- /** Returns a C-style character string describing the general cause of
- * the current error (the same string passed to the ctor). */
- virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
-
-# ifdef _GLIBCXX_TM_TS_INTERNAL
- friend void*
- ::_txnal_logic_error_get_msg(void* e);
-# endif
- };
-
- /** Thrown by the library, or by you, to report domain errors (domain in
- * the mathematical sense). */
- class domain_error : public logic_error
- {
- public:
- explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
- domain_error(const domain_error&) = default;
- domain_error& operator=(const domain_error&) = default;
- domain_error(domain_error&&) = default;
- domain_error& operator=(domain_error&&) = default;
-#endif
- virtual ~domain_error() _GLIBCXX_NOTHROW;
- };
-
- /** Thrown to report invalid arguments to functions. */
- class invalid_argument : public logic_error
- {
- public:
- explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
- invalid_argument(const invalid_argument&) = default;
- invalid_argument& operator=(const invalid_argument&) = default;
- invalid_argument(invalid_argument&&) = default;
- invalid_argument& operator=(invalid_argument&&) = default;
-#endif
- virtual ~invalid_argument() _GLIBCXX_NOTHROW;
- };
-
- /** Thrown when an object is constructed that would exceed its maximum
- * permitted size (e.g., a basic_string instance). */
- class length_error : public logic_error
- {
- public:
- explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
- length_error(const length_error&) = default;
- length_error& operator=(const length_error&) = default;
- length_error(length_error&&) = default;
- length_error& operator=(length_error&&) = default;
-#endif
- virtual ~length_error() _GLIBCXX_NOTHROW;
- };
-
- /** This represents an argument whose value is not within the expected
- * range (e.g., boundary checks in basic_string). */
- class out_of_range : public logic_error
- {
- public:
- explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
- out_of_range(const out_of_range&) = default;
- out_of_range& operator=(const out_of_range&) = default;
- out_of_range(out_of_range&&) = default;
- out_of_range& operator=(out_of_range&&) = default;
-#endif
- virtual ~out_of_range() _GLIBCXX_NOTHROW;
- };
-
- /** Runtime errors represent problems outside the scope of a program;
- * they cannot be easily predicted and can generally only be caught as
- * the program executes.
- * @brief One of two subclasses of exception.
- */
- class runtime_error : public exception
- {
- __cow_string _M_msg;
-
- public:
- /** Takes a character string describing the error. */
- explicit
- runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-
-#if __cplusplus >= 201103L
- explicit
- runtime_error(const char*) _GLIBCXX_TXN_SAFE;
-
- runtime_error(runtime_error&&) noexcept;
- runtime_error& operator=(runtime_error&&) noexcept;
-#endif
-
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
- runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
- runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
-#elif __cplusplus >= 201103L
- runtime_error(const runtime_error&) = default;
- runtime_error& operator=(const runtime_error&) = default;
-#endif
-
- virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
-
- /** Returns a C-style character string describing the general cause of
- * the current error (the same string passed to the ctor). */
- virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
-
-# ifdef _GLIBCXX_TM_TS_INTERNAL
- friend void*
- ::_txnal_runtime_error_get_msg(void* e);
-# endif
- };
-
- /** Thrown to indicate range errors in internal computations. */
- class range_error : public runtime_error
- {
- public:
- explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
- range_error(const range_error&) = default;
- range_error& operator=(const range_error&) = default;
- range_error(range_error&&) = default;
- range_error& operator=(range_error&&) = default;
-#endif
- virtual ~range_error() _GLIBCXX_NOTHROW;
- };
-
- /** Thrown to indicate arithmetic overflow. */
- class overflow_error : public runtime_error
- {
- public:
- explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
- overflow_error(const overflow_error&) = default;
- overflow_error& operator=(const overflow_error&) = default;
- overflow_error(overflow_error&&) = default;
- overflow_error& operator=(overflow_error&&) = default;
-#endif
- virtual ~overflow_error() _GLIBCXX_NOTHROW;
- };
-
- /** Thrown to indicate arithmetic underflow. */
- class underflow_error : public runtime_error
- {
- public:
- explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
-#if __cplusplus >= 201103L
- explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
- underflow_error(const underflow_error&) = default;
- underflow_error& operator=(const underflow_error&) = default;
- underflow_error(underflow_error&&) = default;
- underflow_error& operator=(underflow_error&&) = default;
-#endif
- virtual ~underflow_error() _GLIBCXX_NOTHROW;
- };
-
- /// @} group exceptions
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+#include <bits/stdexcept.h>
#endif /* _GLIBCXX_STDEXCEPT */
--- libstdc++-v3/include/std/optional.jj 2025-08-12 18:31:42.180614219 +0200
+++ libstdc++-v3/include/std/optional 2025-08-12 18:32:56.409661549 +0200
@@ -38,6 +38,7 @@
#define __glibcxx_want_optional
#define __glibcxx_want_optional_range_support
#define __glibcxx_want_constrained_equality
+#define __glibcxx_want_constexpr_exceptions
#include <bits/version.h>
#ifdef __cpp_lib_optional // C++ >= 17
@@ -106,12 +107,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bad_optional_access() = default;
virtual ~bad_optional_access() = default;
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr
+#endif
const char* what() const noexcept override
{ return "bad optional access"; }
};
// XXX Does not belong here.
- [[__noreturn__]] inline void
+ [[__noreturn__]]
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr
+#else
+ inline
+#endif
+ void
__throw_bad_optional_access()
{ _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
--- libstdc++-v3/include/std/expected.jj 2025-08-12 18:31:42.178614245 +0200
+++ libstdc++-v3/include/std/expected 2025-08-12 18:32:56.408661562 +0200
@@ -36,6 +36,7 @@
#define __glibcxx_want_expected
#define __glibcxx_want_freestanding_expected
#define __glibcxx_want_constrained_equality
+#define __glibcxx_want_constexpr_exceptions
#include <bits/version.h>
#ifdef __cpp_lib_expected // C++ >= 23 && __cpp_concepts >= 202002L
@@ -77,21 +78,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Er>
class bad_expected_access;
+#if __cpp_lib_constexpr_exceptions >= 202502L
+#define _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS constexpr
+#else
+#define _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
+#endif
+
template<>
class bad_expected_access<void> : public exception
{
protected:
- bad_expected_access() noexcept { }
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS bad_expected_access() noexcept { }
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
bad_expected_access(const bad_expected_access&) noexcept = default;
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
bad_expected_access(bad_expected_access&&) noexcept = default;
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
bad_expected_access& operator=(const bad_expected_access&) noexcept = default;
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
bad_expected_access& operator=(bad_expected_access&&) noexcept = default;
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
~bad_expected_access() = default;
public:
[[nodiscard]]
- const char*
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const char*
what() const noexcept override
{ return "bad access to std::expected without expected value"; }
};
@@ -99,28 +111,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Er>
class bad_expected_access : public bad_expected_access<void> {
public:
- explicit
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS explicit
bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
// XXX const char* what() const noexcept override;
[[nodiscard]]
- _Er&
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS _Er&
error() & noexcept
{ return _M_unex; }
[[nodiscard]]
- const _Er&
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const _Er&
error() const & noexcept
{ return _M_unex; }
[[nodiscard]]
- _Er&&
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS _Er&&
error() && noexcept
{ return std::move(_M_unex); }
[[nodiscard]]
- const _Er&&
+ _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const _Er&&
error() const && noexcept
{ return std::move(_M_unex); }
--- libstdc++-v3/include/std/format.jj 2025-08-12 18:31:42.179614232 +0200
+++ libstdc++-v3/include/std/format 2025-08-12 18:32:56.411661524 +0200
@@ -38,6 +38,7 @@
#define __glibcxx_want_format
#define __glibcxx_want_format_ranges
#define __glibcxx_want_format_uchar
+#define __glibcxx_want_constexpr_exceptions
#include <bits/version.h>
#ifdef __cpp_lib_format // C++ >= 20 && HOSTED
@@ -214,12 +215,20 @@ namespace __format
formatter& operator=(const formatter&) = delete;
};
+#if __cpp_lib_constexpr_exceptions >= 202502L
+#define _GLIBCXX_CONSTEXPR_FORMAT_ERROR constexpr
+#else
+#define _GLIBCXX_CONSTEXPR_FORMAT_ERROR
+#endif
+
// [format.error], class format_error
class format_error : public runtime_error
{
public:
- explicit format_error(const string& __what) : runtime_error(__what) { }
- explicit format_error(const char* __what) : runtime_error(__what) { }
+ _GLIBCXX_CONSTEXPR_FORMAT_ERROR explicit format_error(const string& __what)
+ : runtime_error(__what) { }
+ _GLIBCXX_CONSTEXPR_FORMAT_ERROR explicit format_error(const char* __what)
+ : runtime_error(__what) { }
};
/// @cond undocumented
@@ -228,6 +237,8 @@ namespace __format
__throw_format_error(const char* __what)
{ _GLIBCXX_THROW_OR_ABORT(format_error(__what)); }
+#undef _GLIBCXX_CONSTEXPR_FORMAT_ERROR
+
namespace __format
{
// XXX use named functions for each constexpr error?
--- libstdc++-v3/include/std/variant.jj 2025-08-12 18:31:42.183614181 +0200
+++ libstdc++-v3/include/std/variant 2025-08-12 18:32:56.409661549 +0200
@@ -36,6 +36,7 @@
#define __glibcxx_want_freestanding_variant
#define __glibcxx_want_variant
#define __glibcxx_want_constrained_equality
+#define __glibcxx_want_constexpr_exceptions
#include <bits/version.h>
#ifdef __cpp_lib_variant // C++ >= 17
@@ -1394,24 +1395,33 @@ namespace __detail::__variant
&& (is_swappable_v<_Types> && ...))>
swap(variant<_Types...>&, variant<_Types...>&) = delete;
- [[noreturn]] void __throw_bad_variant_access(unsigned);
+#if __cpp_lib_constexpr_exceptions >= 202502L
+#define _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS constexpr
+#else
+#define _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
+#endif
+ [[noreturn]] _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS void
+ __throw_bad_variant_access(unsigned);
class bad_variant_access : public exception
{
public:
- bad_variant_access() noexcept { }
+ _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS bad_variant_access() noexcept { }
- const char* what() const noexcept override
+ _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS const char* what()
+ const noexcept override
{ return _M_reason; }
private:
// Must only be called with a string literal
+ _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { }
// Must point to a string with static storage duration:
const char* _M_reason = "bad variant access";
- friend void __throw_bad_variant_access([[maybe_unused]] unsigned __n)
+ friend _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS void
+ __throw_bad_variant_access([[maybe_unused]] unsigned __n)
{
[[maybe_unused]] static constexpr const char* __reasons[] = {
"std::get: wrong index for variant",
@@ -1421,6 +1431,7 @@ namespace __detail::__variant
};
_GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
}
+#undef _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
};
template<typename... _Types>
--- libstdc++-v3/testsuite/18_support/exception/version.cc.jj 2025-08-12 18:31:42.194614040 +0200
+++ libstdc++-v3/testsuite/18_support/exception/version.cc 2025-08-12 18:32:56.422661382 +0200
@@ -3,7 +3,8 @@
#include <exception>
-#ifdef __cpp_lib_constexpr_exceptions
-# error "Feature test macro for constexpr_exceptions should not be provided by <exception>"
+#ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <exception>"
+#elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <exception>"
#endif
-
--- libstdc++-v3/testsuite/19_diagnostics/runtime_error/constexpr.cc.jj 2025-08-12 18:32:56.422661382 +0200
+++ libstdc++-v3/testsuite/19_diagnostics/runtime_error/constexpr.cc 2025-08-12 18:32:56.422661382 +0200
@@ -0,0 +1,73 @@
+// { dg-do compile { target c++26 } }
+
+#include <string>
+#include <stdexcept>
+#include <testsuite_hooks.h>
+
+template <typename T>
+constexpr bool test01()
+{
+ try
+ {
+ std::string s = "This is the first runtime error";
+ throw T(s);
+ }
+ catch (const T &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the first runtime error" );
+ }
+ try
+ {
+ throw T("This is the second runtime error");
+ }
+ catch (const std::runtime_error &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the second runtime error" );
+ }
+ std::string s = "This is the third runtime error";
+ T l(s);
+ try
+ {
+ throw T(l);
+ }
+ catch (const std::runtime_error &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the third runtime error" );
+ }
+ VERIFY( std::string(l.what()) == "This is the third runtime error" );
+ s = "This is the fourth runtime error";
+ l = T(s);
+ try
+ {
+ throw T(std::move(l));
+ }
+ catch (const T &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the fourth runtime error" );
+ }
+ T l2(s);
+ l2 = T("This is the fifth runtime error");
+ VERIFY( std::string(l2.what()) == "This is the fifth runtime error" );
+ T l3("This is the sixth runtime error");
+ VERIFY( std::string(l3.what()) == "This is the sixth runtime error" );
+ l3 = l2;
+ VERIFY( std::string(l2.what()) == "This is the fifth runtime error" );
+ VERIFY( std::string(l3.what()) == "This is the fifth runtime error" );
+ l3 = T("This is the seventh runtime error");
+ l2 = std::move(l3);
+ VERIFY( std::string(l2.what()) == "This is the seventh runtime error" );
+ return true;
+}
+
+static_assert(test01<std::runtime_error>());
+static_assert(test01<std::range_error>());
+static_assert(test01<std::overflow_error>());
+static_assert(test01<std::underflow_error>());
+
+int main(void)
+{
+ test01<std::runtime_error>();
+ test01<std::range_error>();
+ test01<std::overflow_error>();
+ test01<std::underflow_error>();
+}
--- libstdc++-v3/testsuite/19_diagnostics/headers/stdexcept/version.cc.jj 2025-08-12 18:32:56.422661382 +0200
+++ libstdc++-v3/testsuite/19_diagnostics/headers/stdexcept/version.cc 2025-08-12 18:32:56.422661382 +0200
@@ -0,0 +1,10 @@
+// { dg-do preprocess { target c++26 } }
+// { dg-add-options no_pch }
+
+#include <stdexcept>
+
+#ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <stdexcept>"
+#elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <stdexcept>"
+#endif
--- libstdc++-v3/testsuite/19_diagnostics/logic_error/constexpr.cc.jj 2025-08-12 18:32:56.422661382 +0200
+++ libstdc++-v3/testsuite/19_diagnostics/logic_error/constexpr.cc 2025-08-12 18:32:56.422661382 +0200
@@ -0,0 +1,75 @@
+// { dg-do compile { target c++26 } }
+
+#include <string>
+#include <stdexcept>
+#include <testsuite_hooks.h>
+
+template <typename T>
+constexpr bool test01()
+{
+ try
+ {
+ std::string s = "This is the first logic error";
+ throw T(s);
+ }
+ catch (const T &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the first logic error" );
+ }
+ try
+ {
+ throw T("This is the second logic error");
+ }
+ catch (const std::logic_error &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the second logic error" );
+ }
+ std::string s = "This is the third logic error";
+ T l(s);
+ try
+ {
+ throw T(l);
+ }
+ catch (const std::logic_error &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the third logic error" );
+ }
+ VERIFY( std::string(l.what()) == "This is the third logic error" );
+ s = "This is the fourth logic error";
+ l = T(s);
+ try
+ {
+ throw T(std::move(l));
+ }
+ catch (const T &x)
+ {
+ VERIFY( std::string(x.what()) == "This is the fourth logic error" );
+ }
+ T l2(s);
+ l2 = T("This is the fifth logic error");
+ VERIFY( std::string(l2.what()) == "This is the fifth logic error" );
+ T l3("This is the sixth logic error");
+ VERIFY( std::string(l3.what()) == "This is the sixth logic error" );
+ l3 = l2;
+ VERIFY( std::string(l2.what()) == "This is the fifth logic error" );
+ VERIFY( std::string(l3.what()) == "This is the fifth logic error" );
+ l3 = T("This is the seventh logic error");
+ l2 = std::move(l3);
+ VERIFY( std::string(l2.what()) == "This is the seventh logic error" );
+ return true;
+}
+
+static_assert(test01<std::logic_error>());
+static_assert(test01<std::domain_error>());
+static_assert(test01<std::invalid_argument>());
+static_assert(test01<std::length_error>());
+static_assert(test01<std::out_of_range>());
+
+int main(void)
+{
+ test01<std::logic_error>();
+ test01<std::domain_error>();
+ test01<std::invalid_argument>();
+ test01<std::length_error>();
+ test01<std::out_of_range>();
+}
--- libstdc++-v3/testsuite/20_util/expected/observers.cc.jj 2025-08-12 18:31:42.195614027 +0200
+++ libstdc++-v3/testsuite/20_util/expected/observers.cc 2025-08-12 18:32:56.422661382 +0200
@@ -77,7 +77,10 @@ test_value()
return true;
}
-void
+#if __cpp_lib_constexpr_exceptions >= 202502L
+constexpr
+#endif
+bool
test_value_throw()
{
std::expected<int, int> e1 = std::unexpected(9);
@@ -87,6 +90,8 @@ test_value_throw()
VERIFY( false );
} catch (const std::bad_expected_access<int>& e) {
VERIFY( e.error() == 9 );
+ long c = e.what()[0];
+ VERIFY( c == e.what()[0] );
}
try {
std::move(e1).value();
@@ -122,6 +127,7 @@ test_value_throw()
} catch (const std::bad_expected_access<int>& e) {
VERIFY( e.error() == 8 );
}
+ return true;
}
constexpr bool
@@ -218,6 +224,9 @@ int main()
test_has_value();
static_assert( test_value() );
test_value();
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ static_assert( test_value_throw() );
+#endif
test_value_throw();
static_assert( test_error() );
test_error();
--- libstdc++-v3/testsuite/20_util/expected/version.cc.jj 2025-08-12 18:31:42.195614027 +0200
+++ libstdc++-v3/testsuite/20_util/expected/version.cc 2025-08-12 18:32:56.423661370 +0200
@@ -15,8 +15,17 @@
# error "Feature-test macro for freestanding expected has wrong value in <version>"
#endif
+#if __cplusplus > 202302L
+# ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <version>"
+# elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <version>"
+# endif
+#endif
+
#undef __cpp_lib_expected
#undef __cpp_lib_freestanding_expected
+#undef __cpp_lib_constexpr_exceptions
#include <expected>
#ifndef __cpp_lib_expected
@@ -30,3 +39,11 @@
#elif __cpp_lib_freestanding_expected != 202311L
# error "Feature-test macro for freestanding expected has wrong value in <expected>"
#endif
+
+#if __cplusplus > 202302L
+# ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <expected>"
+# elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <expected>"
+# endif
+#endif
--- libstdc++-v3/testsuite/20_util/variant/constexpr.cc.jj 2025-08-12 18:31:42.197614001 +0200
+++ libstdc++-v3/testsuite/20_util/variant/constexpr.cc 2025-08-12 18:32:56.423661370 +0200
@@ -11,6 +11,9 @@
# error "Feature test macro for variant has wrong value for C++20 in <variant>"
#endif
+#if __cpp_lib_constexpr_exceptions >= 202502L
+#include <string>
+#endif
#include <testsuite_hooks.h>
@@ -51,6 +54,39 @@ test_assign()
static_assert( test_assign() );
+#if __cpp_lib_constexpr_exceptions >= 202502L
+constexpr bool test_get()
+{
+ VERIFY(std::get<1>(std::variant<int, std::string>("a")) == "a");
+ VERIFY(std::get<std::string>(std::variant<int, std::string>("a")) == "a");
+ {
+ try
+ {
+ std::get<0>(std::variant<int, std::string>("a"));
+ }
+ catch (const std::bad_variant_access& x)
+ {
+ long c = x.what()[0];
+ VERIFY( c == x.what()[0] );
+ }
+ }
+ {
+ try
+ {
+ std::get<int>(std::variant<int, std::string>("a"));
+ }
+ catch (const std::bad_variant_access& x)
+ {
+ long c = x.what()[0];
+ VERIFY( c == x.what()[0] );
+ }
+ }
+ return true;
+}
+
+static_assert (test_get() );
+#endif
+
constexpr bool
test_emplace()
{
--- libstdc++-v3/testsuite/20_util/variant/version.cc.jj 2025-08-12 18:31:42.197614001 +0200
+++ libstdc++-v3/testsuite/20_util/variant/version.cc 2025-08-12 18:32:56.423661370 +0200
@@ -19,8 +19,17 @@
#endif
#endif
+#if __cplusplus > 202302L
+#ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <version>"
+#elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <version>"
+#endif
+#endif
+
#undef __cpp_lib_variant
#undef __cpp_lib_freestanding_variant
+#undef __cpp_lib_constexpr_exceptions
#include <variant>
#if __cplusplus >= 202302L
@@ -30,3 +39,11 @@
# error "Feature test macro for freestanding std::variant has wrong value in <variant>"
#endif
#endif
+
+#if __cplusplus > 202302L
+#ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <variant>"
+#elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <variant>"
+#endif
+#endif
--- libstdc++-v3/testsuite/20_util/optional/constexpr/observers/3.cc.jj 2025-08-12 18:31:42.196614014 +0200
+++ libstdc++-v3/testsuite/20_util/optional/constexpr/observers/3.cc 2025-08-12 18:32:56.423661370 +0200
@@ -18,12 +18,45 @@
// <http://www.gnu.org/licenses/>.
#include <optional>
+#include <testsuite_hooks.h>
struct value_type
{
int i;
};
+#if __cpp_lib_constexpr_exceptions >= 202502L
+void eat(int x)
+{
+}
+
+constexpr bool test01()
+{
+ enum outcome_type { nothrow, caught, bad_catch };
+
+ outcome_type outcome {};
+ std::optional<value_type> o = std::nullopt;
+
+ try
+ {
+ eat(o.value().i);
+ }
+ catch(std::bad_optional_access const& x)
+ {
+ outcome = caught;
+ long c = x.what()[0];
+ VERIFY( c == x.what()[0] );
+ }
+ catch(...)
+ { outcome = bad_catch; }
+
+ VERIFY( outcome == caught );
+ return true;
+}
+
+static_assert( test01() );
+#endif
+
int main()
{
constexpr std::optional<value_type> o { value_type { 51 } };
--- libstdc++-v3/testsuite/20_util/optional/version.cc.jj 2025-08-12 18:31:42.196614014 +0200
+++ libstdc++-v3/testsuite/20_util/optional/version.cc 2025-08-12 18:32:56.423661370 +0200
@@ -27,11 +27,18 @@
# elif __cpp_lib_optional_range_support != 202406L
# error "Feature test macro for optional range support has wrong value for C++26 in <version>"
# endif
+
+# ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <version>"
+# elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <version>"
+# endif
#endif
#undef __cpp_lib_optional
#undef __cpp_lib_freestanding_optional
#undef __cpp_lib_optional_range_support
+#undef __cpp_lib_constexpr_exceptions
#include <optional>
#if __cplusplus >= 202302L
@@ -49,4 +56,10 @@
# if __cpp_lib_optional_range_support != 202406L
# error "Feature test macro for optional range support has wrong value for C++26 in <optional>"
# endif
+
+# ifndef __cpp_lib_constexpr_exceptions
+# error "Feature test macro for constexpr_exceptions is missing in <optional>"
+# elif __cpp_lib_constexpr_exceptions < 202502L
+# error "Feature test macro for constexpr_exceptions has wrong value in <optional>"
+# endif
#endif
--- libstdc++-v3/include/std/future.jj 2025-08-12 18:31:42.179614232 +0200
+++ libstdc++-v3/include/std/future 2025-08-12 18:32:56.413661498 +0200
@@ -34,6 +34,8 @@
#endif
#include <bits/requires_hosted.h> // concurrency
+#define __glibcxx_exc_want_throw_future_error
+#include <bits/functexcept.h>
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
--- libstdc++-v3/include/std/shared_mutex.jj 2025-08-12 18:31:42.181614206 +0200
+++ libstdc++-v3/include/std/shared_mutex 2025-08-12 18:32:56.412661511 +0200
@@ -39,6 +39,8 @@
#include <bits/chrono.h>
#include <bits/error_constants.h>
+#define __glibcxx_exc_want_throw_bad_alloc
+#define __glibcxx_exc_want_throw_system_error
#include <bits/functexcept.h>
#include <bits/move.h> // move, __exchange
#include <bits/std_mutex.h> // defer_lock_t
--- libstdc++-v3/include/std/flat_map.jj 2025-08-12 18:31:42.178614245 +0200
+++ libstdc++-v3/include/std/flat_map 2025-08-12 18:32:56.410661537 +0200
@@ -47,6 +47,7 @@
#include <ranges> // views::zip
#include <type_traits>
#include <vector>
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
#include <bits/stl_algo.h>
#include <bits/stl_function.h> // less
--- libstdc++-v3/include/std/syncstream.jj 2025-08-12 18:31:42.182614194 +0200
+++ libstdc++-v3/include/std/syncstream 2025-08-12 18:32:56.411661524 +0200
@@ -45,7 +45,6 @@
#include <bits/alloc_traits.h>
#include <bits/allocator.h>
-#include <bits/functexcept.h>
#include <bits/functional_hash.h>
#include <bits/std_mutex.h>
--- libstdc++-v3/include/std/mutex.jj 2025-08-12 18:31:42.180614219 +0200
+++ libstdc++-v3/include/std/mutex 2025-08-12 18:32:56.412661511 +0200
@@ -43,6 +43,7 @@
#include <type_traits> // is_same_v
#include <errno.h> // EAGAIN, EDEADLK
#include <bits/chrono.h> // duration, time_point, is_clock_v
+#define __glibcxx_exc_want_throw_system_error
#include <bits/functexcept.h> // __throw_system_error
#include <bits/invoke.h> // __invoke
#include <bits/move.h> // std::forward
--- libstdc++-v3/include/std/flat_set.jj 2025-08-12 18:31:42.178614245 +0200
+++ libstdc++-v3/include/std/flat_set 2025-08-12 18:32:56.410661537 +0200
@@ -46,7 +46,6 @@
#include <optional>
#include <type_traits>
#include <vector>
-#include <bits/functexcept.h>
#include <bits/stl_algo.h>
#include <bits/stl_function.h> // less
#include <bits/stl_pair.h>
--- libstdc++-v3/include/std/bitset.jj 2025-08-12 18:31:42.177614258 +0200
+++ libstdc++-v3/include/std/bitset 2025-08-12 18:32:56.412661511 +0200
@@ -46,6 +46,10 @@
#pragma GCC system_header
#endif
+#define __glibcxx_exc_want_throw_overflow_error
+#define __glibcxx_exc_want_throw_out_of_range
+#define __glibcxx_exc_want_throw_logic_error
+#define __glibcxx_exc_want_throw_invalid_argument
#include <bits/functexcept.h> // For invalid_argument, out_of_range,
// overflow_error
#include <bits/stl_algobase.h> // For std::fill
--- libstdc++-v3/include/std/print.jj 2025-08-12 18:31:42.181614206 +0200
+++ libstdc++-v3/include/std/print 2025-08-12 18:32:56.408661562 +0200
@@ -43,6 +43,7 @@
#include <format>
#include <cstdio>
#include <cerrno>
+#define __glibcxx_exc_want_throw_system_error
#include <bits/functexcept.h>
#ifdef _WIN32
--- libstdc++-v3/include/std/string_view.jj 2025-08-12 18:31:42.182614194 +0200
+++ libstdc++-v3/include/std/string_view 2025-08-12 18:32:56.409661549 +0200
@@ -48,7 +48,11 @@
#if __cplusplus >= 201703L
#include <bits/char_traits.h>
+#ifndef __glibcxx_exc_in_string
+#define __glibcxx_exc_in_string 2
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
+#endif
#include <bits/functional_hash.h>
#include <bits/range_access.h>
#include <bits/stl_algobase.h>
@@ -910,6 +914,15 @@ _GLIBCXX_END_NAMESPACE_VERSION
#include <bits/string_view.tcc>
+#if __glibcxx_exc_in_string == 2
+#undef __glibcxx_exc_in_string
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+ && __cpp_constexpr_exceptions >= 202411L)
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
+#endif
+#endif
+
#endif // __cplusplus <= 201402L
-#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
+#endif // _GLIBCXX_STRING_VIEW
--- libstdc++-v3/include/std/array.jj 2025-08-12 18:31:42.176614271 +0200
+++ libstdc++-v3/include/std/array 2025-08-12 18:32:56.410661537 +0200
@@ -41,6 +41,7 @@
#include <initializer_list>
#include <type_traits>
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/range_access.h> // std::begin, std::end etc.
--- libstdc++-v3/include/std/inplace_vector.jj 2025-08-12 18:31:42.179614232 +0200
+++ libstdc++-v3/include/std/inplace_vector 2025-08-12 18:32:56.408661562 +0200
@@ -38,6 +38,8 @@
#ifdef __glibcxx_inplace_vector // C++ >= 26
#include <compare>
#include <initializer_list>
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
#include <bits/range_access.h>
#include <bits/ranges_base.h> // borrowed_iterator_t, __detail::__container_compatible_range
#include <bits/ranges_util.h> // subrange
--- libstdc++-v3/include/std/string.jj 2025-08-12 18:31:42.181614206 +0200
+++ libstdc++-v3/include/std/string 2025-08-12 18:32:56.412661511 +0200
@@ -40,6 +40,7 @@
#include <bits/requires_hosted.h> // containers
#include <bits/c++config.h>
+#define __glibcxx_exc_in_string 1
#include <bits/stringfwd.h>
#include <bits/char_traits.h>
#include <bits/allocator.h>
@@ -50,11 +51,26 @@
#include <bits/stl_iterator.h>
#include <bits/stl_function.h> // For less
#include <ext/numeric_traits.h>
+#define __glibcxx_exc_want_throw_length_error
+#define __glibcxx_exc_want_throw_logic_error
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/refwrap.h>
#include <bits/range_access.h>
#include <bits/basic_string.h>
#include <bits/basic_string.tcc>
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+ && __cpp_constexpr_exceptions >= 202411L)
+#include <bits/stdexcept.h>
+#undef __glibcxx_exc_in_string
+#define __glibcxx_exc_want_throw_length_error
+#define __glibcxx_exc_want_throw_logic_error
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
+#else
+#undef __glibcxx_exc_in_string
+#endif
#define __glibcxx_want_algorithm_default_value_type
#define __glibcxx_want_allocator_traits_is_always_equal
--- libstdc++-v3/include/std/deque.jj 2025-08-12 18:31:42.177614258 +0200
+++ libstdc++-v3/include/std/deque 2025-08-12 18:32:56.411661524 +0200
@@ -61,6 +61,8 @@
#include <bits/requires_hosted.h> // containers are hosted only
+#define __glibcxx_exc_want_throw_length_error
+#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_construct.h>
--- libstdc++-v3/include/bits/new_allocator.h.jj 2025-08-12 18:31:42.159614489 +0200
+++ libstdc++-v3/include/bits/new_allocator.h 2025-08-12 18:32:56.415661472 +0200
@@ -32,6 +32,8 @@
#include <bits/c++config.h>
#include <new>
+#define __glibcxx_exc_want_throw_bad_alloc
+#define __glibcxx_exc_want_throw_bad_array_new_length
#include <bits/functexcept.h>
#include <bits/move.h>
#if __cplusplus >= 201103L
--- libstdc++-v3/include/bits/stl_algobase.h.jj 2025-08-12 18:31:42.163614438 +0200
+++ libstdc++-v3/include/bits/stl_algobase.h 2025-08-12 18:32:56.413661498 +0200
@@ -57,7 +57,6 @@
#define _STL_ALGOBASE_H 1
#include <bits/c++config.h>
-#include <bits/functexcept.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
#include <ext/numeric_traits.h>
--- libstdc++-v3/include/bits/stl_vector.h.jj 2025-08-12 18:31:42.165614412 +0200
+++ libstdc++-v3/include/bits/stl_vector.h 2025-08-12 18:32:56.414661485 +0200
@@ -57,6 +57,8 @@
#define _STL_VECTOR_H 1
#include <bits/stl_iterator_base_funcs.h>
+#define __glibcxx_exc_want_throw_out_of_range
+#define __glibcxx_exc_want_throw_length_error
#include <bits/functexcept.h>
#include <bits/concept_check.h>
#if __cplusplus >= 201103L
--- libstdc++-v3/include/bits/memory_resource.h.jj 2025-08-12 18:31:42.159614489 +0200
+++ libstdc++-v3/include/bits/memory_resource.h 2025-08-12 18:32:56.414661485 +0200
@@ -38,6 +38,7 @@
#include <new> // operator new(size_t, void*)
#include <cstddef> // size_t, max_align_t, byte
+#define __glibcxx_exc_want_throw_bad_array_new_length
#include <bits/functexcept.h> // __throw_bad_array_new_length
#include <bits/uses_allocator.h> // allocator_arg_t, __use_alloc
#include <bits/uses_allocator_args.h> // uninitialized_construct_using_alloc
--- libstdc++-v3/include/bits/std_mutex.h.jj 2025-08-12 18:31:42.160614476 +0200
+++ libstdc++-v3/include/bits/std_mutex.h 2025-08-12 18:32:56.416661460 +0200
@@ -39,6 +39,7 @@
#else
#include <errno.h> // EBUSY
+#define __glibcxx_exc_want_throw_system_error
#include <bits/functexcept.h>
#include <bits/gthr.h>
--- libstdc++-v3/include/bits/stdexcept.h.jj 2025-08-12 18:32:56.417661447 +0200
+++ libstdc++-v3/include/bits/stdexcept.h 2025-08-12 18:32:56.417661447 +0200
@@ -0,0 +1,583 @@
+// Standard exception classes -*- C++ -*-
+
+// Copyright (C) 2001-2025 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
+// 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.
+
+// 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/>.
+
+/** @file bits/stdexcept.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{stdexcept} */
+
+#ifndef _GLIBCXX_STDEXCEPT_H
+#define _GLIBCXX_STDEXCEPT_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#include <exception>
+#include <string>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if _GLIBCXX_USE_DUAL_ABI
+#if _GLIBCXX_USE_CXX11_ABI
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ struct __cow_constexpr_string;
+ namespace __detail
+ {
+ extern "C"
+ {
+ void _ZNSt12__cow_stringC2EPKcm(__cow_constexpr_string*, const char*,
+ unsigned long);
+ void _ZNSt12__cow_stringC2EPKcj(__cow_constexpr_string*, const char*,
+ unsigned int);
+ void _ZNSt12__cow_stringC2EPKcy(__cow_constexpr_string*, const char*,
+ unsigned long long);
+ void _ZNSt12__cow_stringC2EPKc(__cow_constexpr_string*, const char*);
+ void _ZNSt12__cow_stringC2ERKS_(__cow_constexpr_string*,
+ const __cow_constexpr_string&) noexcept;
+ void _ZNSt12__cow_stringC2EOS_(__cow_constexpr_string*,
+ __cow_constexpr_string&&) noexcept;
+ void _ZNSt12__cow_stringD2Ev(__cow_constexpr_string*);
+ __cow_constexpr_string&
+ _ZNSt12__cow_stringaSERKS_(__cow_constexpr_string*,
+ const __cow_constexpr_string&) noexcept;
+ __cow_constexpr_string&
+ _ZNSt12__cow_stringaSEOS_(__cow_constexpr_string*,
+ __cow_constexpr_string&&) noexcept;
+ const char*
+ _ZNKSt12__cow_string5c_strEv(const __cow_constexpr_string*) noexcept;
+ }
+ } // namespace __detail
+
+ // Emulates an old COW string when the new std::string is in use,
+ // but in addition is constexpr and uses the __cow_string out of
+ // line cdtors/methods unless manifestly constant evaluated.
+ struct __cow_constexpr_string
+ {
+ union {
+ const char* _M_p;
+ char _M_bytes[sizeof(const char*)];
+ string* _M_str;
+ };
+
+ [[__gnu__::__always_inline__]] constexpr
+ __cow_constexpr_string(const string& __o)
+ {
+ if consteval {
+ _M_str = new string(__o);
+ } else {
+ __cow_constexpr_string_ctor(__o.c_str(), __o.length());
+ }
+ }
+
+ [[__gnu__::__always_inline__]] inline void
+ __cow_constexpr_string_ctor(const char *__s, unsigned long __l)
+ {
+ __detail::_ZNSt12__cow_stringC2EPKcm(this, __s, __l);
+ }
+
+ [[__gnu__::__always_inline__]] inline void
+ __cow_constexpr_string_ctor(const char *__s, unsigned int __l)
+ {
+ __detail::_ZNSt12__cow_stringC2EPKcj(this, __s, __l);
+ }
+
+ [[__gnu__::__always_inline__]] inline void
+ __cow_constexpr_string_ctor(const char *__s, unsigned long long __l)
+ {
+ __detail::_ZNSt12__cow_stringC2EPKcy(this, __s, __l);
+ }
+
+ [[__gnu__::__always_inline__]] constexpr
+ __cow_constexpr_string(const char* __o)
+ {
+ if consteval {
+ _M_str = new string(__o);
+ } else {
+ __detail::_ZNSt12__cow_stringC2EPKc(this, __o);
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr
+ __cow_constexpr_string(const __cow_constexpr_string& __o) noexcept
+ {
+ if consteval {
+ _M_str = new string(*__o._M_str);
+ } else {
+ __detail::_ZNSt12__cow_stringC2ERKS_(this, __o);
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr __cow_constexpr_string&
+ operator=(const __cow_constexpr_string& __o) noexcept
+ {
+ if consteval {
+ string* __p = _M_str;
+ _M_str = new string(*__o._M_str);
+ delete __p;
+ return *this;
+ } else {
+ return __detail::_ZNSt12__cow_stringaSERKS_(this, __o);
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr
+ ~__cow_constexpr_string()
+ {
+ if consteval {
+ delete _M_str;
+ } else {
+ __detail::_ZNSt12__cow_stringD2Ev(this);
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr
+ __cow_constexpr_string(__cow_constexpr_string&& __o) noexcept
+ {
+ if consteval {
+ _M_str = new string(std::move(*__o._M_str));
+ } else {
+ __detail::_ZNSt12__cow_stringC2EOS_(this, std::move(__o));
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr __cow_constexpr_string&
+ operator=(__cow_constexpr_string&& __o) noexcept
+ {
+ if consteval {
+ string* __p = _M_str;
+ _M_str = new string(std::move(*__o._M_str));
+ delete __p;
+ return *this;
+ } else {
+ return __detail::_ZNSt12__cow_stringaSEOS_(this, std::move(__o));
+ }
+ }
+
+ [[__gnu__::__always_inline__]] constexpr const char*
+ c_str() const noexcept
+ {
+ if consteval {
+ return _M_str->c_str();
+ } else {
+ return __detail::_ZNKSt12__cow_string5c_strEv(this);
+ }
+ }
+ };
+
+ typedef __cow_constexpr_string __cow_string;
+#else
+ // Emulates an old COW string when the new std::string is in use.
+ struct __cow_string
+ {
+ union {
+ const char* _M_p;
+ char _M_bytes[sizeof(const char*)];
+ };
+
+ __cow_string();
+ __cow_string(const std::string&);
+ __cow_string(const char*, size_t);
+ __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
+ __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
+ ~__cow_string();
+#if __cplusplus >= 201103L
+ __cow_string(__cow_string&&) noexcept;
+ __cow_string& operator=(__cow_string&&) noexcept;
+#endif
+ };
+#endif
+
+ typedef basic_string<char> __sso_string;
+#else // _GLIBCXX_USE_CXX11_ABI
+ typedef basic_string<char> __cow_string;
+
+ // Emulates a new SSO string when the old std::string is in use.
+ struct __sso_string
+ {
+ struct __str
+ {
+ const char* _M_p;
+ size_t _M_string_length;
+ char _M_local_buf[16];
+ };
+
+ union {
+ __str _M_s;
+ char _M_bytes[sizeof(__str)];
+ };
+
+ __sso_string() _GLIBCXX_NOTHROW;
+ __sso_string(const std::string&);
+ __sso_string(const char*, size_t);
+ __sso_string(const __sso_string&);
+ __sso_string& operator=(const __sso_string&);
+ ~__sso_string();
+#if __cplusplus >= 201103L
+ __sso_string(__sso_string&&) noexcept;
+ __sso_string& operator=(__sso_string&&) noexcept;
+#endif
+ };
+#endif // _GLIBCXX_USE_CXX11_ABI
+#else // _GLIBCXX_USE_DUAL_ABI
+ typedef basic_string<char> __sso_string;
+ typedef basic_string<char> __cow_string;
+#endif
+
+ /**
+ * @addtogroup exceptions
+ * @{
+ */
+
+ /** Logic errors represent problems in the internal logic of a program;
+ * in theory, these are preventable, and even detectable before the
+ * program runs (e.g., violations of class invariants).
+ * @brief One of two subclasses of exception.
+ */
+ class logic_error : public exception
+ {
+ __cow_string _M_msg;
+
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit
+ logic_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : _M_msg(__arg) {}
+
+ constexpr explicit
+ logic_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : _M_msg(__arg) {}
+
+ constexpr logic_error(logic_error&& __arg) noexcept = default;
+ constexpr logic_error& operator=(logic_error&& __arg) noexcept = default;
+ constexpr logic_error(const logic_error&) noexcept = default;
+ constexpr logic_error& operator=(const logic_error&) noexcept = default;
+
+ constexpr virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
+
+ constexpr virtual const char*
+ what() const _GLIBCXX_TXN_SAFE_DYN noexcept
+ {
+ return _M_msg.c_str();
+ }
+#else
+ /** Takes a character string describing the error. */
+ explicit
+ logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+
+#if __cplusplus >= 201103L
+ explicit
+ logic_error(const char*) _GLIBCXX_TXN_SAFE;
+
+ logic_error(logic_error&&) noexcept;
+ logic_error& operator=(logic_error&&) noexcept;
+#endif
+
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+ logic_error(const logic_error&) _GLIBCXX_NOTHROW;
+ logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
+#elif __cplusplus >= 201103L
+ logic_error(const logic_error&) = default;
+ logic_error& operator=(const logic_error&) = default;
+#endif
+
+ virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
+
+ /** Returns a C-style character string describing the general cause of
+ * the current error (the same string passed to the ctor). */
+ virtual const char*
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
+#endif
+
+# ifdef _GLIBCXX_TM_TS_INTERNAL
+ friend void*
+ ::_txnal_logic_error_get_msg(void* e);
+# endif
+ };
+
+ /** Thrown by the library, or by you, to report domain errors (domain in
+ * the mathematical sense). */
+ class domain_error : public logic_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr explicit domain_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr domain_error(const domain_error&) = default;
+ constexpr domain_error& operator=(const domain_error&) = default;
+ constexpr domain_error(domain_error&&) = default;
+ constexpr domain_error& operator=(domain_error&&) = default;
+ constexpr virtual ~domain_error() _GLIBCXX_NOTHROW { }
+#else
+ explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
+ domain_error(const domain_error&) = default;
+ domain_error& operator=(const domain_error&) = default;
+ domain_error(domain_error&&) = default;
+ domain_error& operator=(domain_error&&) = default;
+#endif
+ virtual ~domain_error() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** Thrown to report invalid arguments to functions. */
+ class invalid_argument : public logic_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr explicit invalid_argument(const char* __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr invalid_argument(const invalid_argument&) = default;
+ constexpr invalid_argument& operator=(const invalid_argument&) = default;
+ constexpr invalid_argument(invalid_argument&&) = default;
+ constexpr invalid_argument& operator=(invalid_argument&&) = default;
+ constexpr virtual ~invalid_argument() _GLIBCXX_NOTHROW { }
+#else
+ explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
+ invalid_argument(const invalid_argument&) = default;
+ invalid_argument& operator=(const invalid_argument&) = default;
+ invalid_argument(invalid_argument&&) = default;
+ invalid_argument& operator=(invalid_argument&&) = default;
+#endif
+ virtual ~invalid_argument() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** Thrown when an object is constructed that would exceed its maximum
+ * permitted size (e.g., a basic_string instance). */
+ class length_error : public logic_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr explicit length_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr length_error(const length_error&) = default;
+ constexpr length_error& operator=(const length_error&) = default;
+ constexpr length_error(length_error&&) = default;
+ constexpr length_error& operator=(length_error&&) = default;
+ constexpr virtual ~length_error() _GLIBCXX_NOTHROW { }
+#else
+ explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
+ length_error(const length_error&) = default;
+ length_error& operator=(const length_error&) = default;
+ length_error(length_error&&) = default;
+ length_error& operator=(length_error&&) = default;
+#endif
+ virtual ~length_error() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** This represents an argument whose value is not within the expected
+ * range (e.g., boundary checks in basic_string). */
+ class out_of_range : public logic_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr explicit out_of_range(const char* __arg) _GLIBCXX_TXN_SAFE
+ : logic_error(__arg) { }
+ constexpr out_of_range(const out_of_range&) = default;
+ constexpr out_of_range& operator=(const out_of_range&) = default;
+ constexpr out_of_range(out_of_range&&) = default;
+ constexpr out_of_range& operator=(out_of_range&&) = default;
+ constexpr virtual ~out_of_range() _GLIBCXX_NOTHROW { }
+#else
+ explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
+ out_of_range(const out_of_range&) = default;
+ out_of_range& operator=(const out_of_range&) = default;
+ out_of_range(out_of_range&&) = default;
+ out_of_range& operator=(out_of_range&&) = default;
+#endif
+ virtual ~out_of_range() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** Runtime errors represent problems outside the scope of a program;
+ * they cannot be easily predicted and can generally only be caught as
+ * the program executes.
+ * @brief One of two subclasses of exception.
+ */
+ class runtime_error : public exception
+ {
+ __cow_string _M_msg;
+
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit
+ runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : _M_msg(__arg) {}
+
+ constexpr explicit
+ runtime_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : _M_msg(__arg) {}
+
+ constexpr runtime_error(runtime_error&&) noexcept = default;
+ constexpr runtime_error& operator=(runtime_error&&) noexcept = default;
+ constexpr runtime_error(const runtime_error&) noexcept = default;
+ runtime_error& operator=(const runtime_error&) noexcept = default;
+
+ constexpr virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
+
+ constexpr virtual const char*
+ what() const _GLIBCXX_TXN_SAFE_DYN noexcept
+ {
+ return _M_msg.c_str();
+ }
+#else
+ /** Takes a character string describing the error. */
+ explicit
+ runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+
+#if __cplusplus >= 201103L
+ explicit
+ runtime_error(const char*) _GLIBCXX_TXN_SAFE;
+
+ runtime_error(runtime_error&&) noexcept;
+ runtime_error& operator=(runtime_error&&) noexcept;
+#endif
+
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+ runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
+ runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
+#elif __cplusplus >= 201103L
+ runtime_error(const runtime_error&) = default;
+ runtime_error& operator=(const runtime_error&) = default;
+#endif
+
+ virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
+
+ /** Returns a C-style character string describing the general cause of
+ * the current error (the same string passed to the ctor). */
+ virtual const char*
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
+#endif
+
+# ifdef _GLIBCXX_TM_TS_INTERNAL
+ friend void*
+ ::_txnal_runtime_error_get_msg(void* e);
+# endif
+ };
+
+ /** Thrown to indicate range errors in internal computations. */
+ class range_error : public runtime_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr explicit range_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr range_error(const range_error&) = default;
+ constexpr range_error& operator=(const range_error&) = default;
+ constexpr range_error(range_error&&) = default;
+ constexpr range_error& operator=(range_error&&) = default;
+ constexpr virtual ~range_error() noexcept { }
+#else
+ explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
+ range_error(const range_error&) = default;
+ range_error& operator=(const range_error&) = default;
+ range_error(range_error&&) = default;
+ range_error& operator=(range_error&&) = default;
+#endif
+ virtual ~range_error() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** Thrown to indicate arithmetic overflow. */
+ class overflow_error : public runtime_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr explicit overflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr overflow_error(const overflow_error&) = default;
+ constexpr overflow_error& operator=(const overflow_error&) = default;
+ constexpr overflow_error(overflow_error&&) = default;
+ constexpr overflow_error& operator=(overflow_error&&) = default;
+ constexpr virtual ~overflow_error() noexcept { }
+#else
+ explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
+ overflow_error(const overflow_error&) = default;
+ overflow_error& operator=(const overflow_error&) = default;
+ overflow_error(overflow_error&&) = default;
+ overflow_error& operator=(overflow_error&&) = default;
+#endif
+ virtual ~overflow_error() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /** Thrown to indicate arithmetic underflow. */
+ class underflow_error : public runtime_error
+ {
+ public:
+#if __cpp_lib_constexpr_exceptions >= 202502L
+ constexpr explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr explicit underflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
+ : runtime_error(__arg) { }
+ constexpr underflow_error(const underflow_error&) = default;
+ constexpr underflow_error& operator=(const underflow_error&) = default;
+ constexpr underflow_error(underflow_error&&) = default;
+ constexpr underflow_error& operator=(underflow_error&&) = default;
+ constexpr virtual ~underflow_error() noexcept { }
+#else
+ explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
+#if __cplusplus >= 201103L
+ explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
+ underflow_error(const underflow_error&) = default;
+ underflow_error& operator=(const underflow_error&) = default;
+ underflow_error(underflow_error&&) = default;
+ underflow_error& operator=(underflow_error&&) = default;
+#endif
+ virtual ~underflow_error() _GLIBCXX_NOTHROW;
+#endif
+ };
+
+ /// @} group exceptions
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif /* _GLIBCXX_STDEXCEPT_H */
--- libstdc++-v3/include/bits/functexcept.h.jj 2025-08-12 18:31:42.154614553 +0200
+++ libstdc++-v3/include/bits/functexcept.h 2025-08-12 18:32:56.416661460 +0200
@@ -33,35 +33,515 @@
// ISO C++ 14882: 19.1 Exception classes
//
-#ifndef _FUNCTEXCEPT_H
-#define _FUNCTEXCEPT_H 1
-
#include <bits/c++config.h>
#include <bits/exception_defines.h>
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+ && __cpp_constexpr_exceptions >= 202411L)
+#if defined(__glibcxx_exc_want_throw_bad_exception) \
+ || defined(__glibcxx_exc_want_throw_all)
+#define __glibcxx_exc_want_exception
+#endif
+#if defined(__glibcxx_exc_want_throw_bad_alloc) \
+ || defined(__glibcxx_exc_want_throw_bad_array_new_length) \
+ || defined(__glibcxx_exc_want_throw_all)
+#define __glibcxx_exc_want_new
+#endif
+#if defined(__glibcxx_exc_want_throw_bad_cast) \
+ || defined(__glibcxx_exc_want_throw_bad_typeid) \
+ || defined(__glibcxx_exc_want_throw_all)
+#define __glibcxx_exc_want_typeinfo
+#endif
+#if defined(__glibcxx_exc_want_throw_logic_error) \
+ || defined(__glibcxx_exc_want_throw_domain_error) \
+ || defined(__glibcxx_exc_want_throw_invalid_argument) \
+ || defined(__glibcxx_exc_want_throw_length_error) \
+ || defined(__glibcxx_exc_want_throw_out_of_range) \
+ || defined(__glibcxx_exc_want_throw_runtime_error) \
+ || defined(__glibcxx_exc_want_throw_range_rror) \
+ || defined(__glibcxx_exc_want_throw_overflow_error) \
+ || defined(__glibcxx_exc_want_throw_underflow_error) \
+ || defined(__glibcxx_exc_want_throw_all)
+#define __glibcxx_exc_want_stdexcept
+#endif
+#endif
+
+#if defined(__glibcxx_exc_want_exception) \
+ || defined(__glibcxx_exc_want_new) \
+ || defined(__glibcxx_exc_want_typeinfo) \
+ || defined(__glibcxx_exc_want_stdexcept)
+#include <bits/exception.h>
+#endif
+
+#if defined(__glibcxx_exc_want_throw_bad_exception) \
+ || defined(__glibcxx_exc_want_throw_bad_alloc) \
+ || defined(__glibcxx_exc_want_throw_bad_array_new_length) \
+ || defined(__glibcxx_exc_want_throw_bad_cast) \
+ || defined(__glibcxx_exc_want_throw_bad_typeid) \
+ || defined(__glibcxx_exc_want_throw_logic_error) \
+ || defined(__glibcxx_exc_want_throw_domain_error) \
+ || defined(__glibcxx_exc_want_throw_invalid_argument) \
+ || defined(__glibcxx_exc_want_throw_length_error) \
+ || defined(__glibcxx_exc_want_throw_out_of_range) \
+ || defined(__glibcxx_exc_want_throw_runtime_error) \
+ || defined(__glibcxx_exc_want_throw_range_rror) \
+ || defined(__glibcxx_exc_want_throw_overflow_error) \
+ || defined(__glibcxx_exc_want_throw_underflow_error) \
+ || defined(__glibcxx_exc_want_throw_ios_failure) \
+ || defined(__glibcxx_exc_want_throw_system_error) \
+ || defined(__glibcxx_exc_want_throw_future_error) \
+ || defined(__glibcxx_exc_want_throw_bad_function_call) \
+ || defined(__glibcxx_exc_want_throw_all) \
+ || defined(__glibcxx_exc_want_exception) \
+ || defined(__glibcxx_exc_want_new) \
+ || defined(__glibcxx_exc_want_typeinfo)
+
+extern "C++" {
+
namespace std _GLIBCXX_VISIBILITY(default)
{
+#if defined(__glibcxx_exc_want_exception) && !defined(__glibcxx_exc_exception)
+#define __glibcxx_exc_exception
+ /** If an %exception is thrown which is not listed in a function's
+ * %exception specification, one of these may be thrown.
+ *
+ * @ingroup exceptions
+ */
+ class bad_exception : public exception
+ {
+ public:
+ _GLIBCXX26_CONSTEXPR bad_exception() _GLIBCXX_USE_NOEXCEPT { }
+
+#if __cplusplus >= 202400L
+ constexpr virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
+
+ constexpr virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN noexcept
+ {
+ return "std::bad_exception";
+ }
+#else
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+ virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+
+ // See comment in eh_exception.cc.
+ virtual const char*
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+#endif
+ };
+#endif
+
+#if defined(__glibcxx_exc_want_new) && !defined(__glibcxx_exc_new)
+#define __glibcxx_exc_new
+ /**
+ * @brief Exception possibly thrown by @c new.
+ * @ingroup exceptions
+ *
+ * @c bad_alloc (or classes derived from it) is used to report allocation
+ * errors from the throwing forms of @c new. */
+ class bad_alloc : public exception
+ {
+ public:
+ _GLIBCXX26_CONSTEXPR bad_alloc() throw() { }
+
+#if __cplusplus >= 201103L
+ _GLIBCXX26_CONSTEXPR bad_alloc(const bad_alloc&) = default;
+ _GLIBCXX26_CONSTEXPR bad_alloc& operator=(const bad_alloc&) = default;
+#endif
+
+#if __cplusplus >= 202400L
+ constexpr virtual ~bad_alloc() noexcept {}
+
+ constexpr virtual const char* what() const noexcept
+ {
+ return "std::bad_alloc";
+ }
+#else
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+ virtual ~bad_alloc() throw();
+
+ // See comment in eh_exception.cc.
+ virtual const char* what() const throw();
+#endif
+ };
+
+#if __cplusplus >= 201103L
+ class bad_array_new_length : public bad_alloc
+ {
+ public:
+ _GLIBCXX26_CONSTEXPR bad_array_new_length() throw() { }
+
+#if __cplusplus >= 202400L
+ constexpr virtual ~bad_array_new_length() noexcept {}
+
+ constexpr virtual const char* what() const noexcept
+ {
+ return "std::bad_array_new_length";
+ }
+#else
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+ virtual ~bad_array_new_length() throw();
+
+ // See comment in eh_exception.cc.
+ virtual const char* what() const throw();
+#endif
+ };
+#endif
+#endif
+
+#if defined(__glibcxx_exc_want_typeinfo) && !defined(__glibcxx_exc_typeinfo)
+#define __glibcxx_exc_typeinfo
+ /**
+ * @brief Thrown during incorrect typecasting.
+ * @ingroup exceptions
+ *
+ * If you attempt an invalid @c dynamic_cast expression, an instance of
+ * this class (or something derived from this class) is thrown. */
+ class bad_cast : public exception
+ {
+ public:
+ _GLIBCXX26_CONSTEXPR bad_cast() _GLIBCXX_USE_NOEXCEPT { }
+
+#if __cplusplus >= 202400L
+ constexpr virtual ~bad_cast() noexcept {}
+
+ constexpr virtual const char* what() const noexcept
+ {
+ return "std::bad_cast";
+ }
+#else
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+ virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT;
+
+ // See comment in eh_exception.cc.
+ virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
+#endif
+ };
+
+ /**
+ * @brief Thrown when a NULL pointer in a @c typeid expression is used.
+ * @ingroup exceptions
+ */
+ class bad_typeid : public exception
+ {
+ public:
+ _GLIBCXX26_CONSTEXPR bad_typeid () _GLIBCXX_USE_NOEXCEPT { }
+
+#if __cplusplus >= 202400L
+ constexpr virtual ~bad_typeid() noexcept {}
+
+ constexpr virtual const char* what() const noexcept
+ {
+ return "std::bad_typeid";
+ }
+#else
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+ virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT;
+
+ // See comment in eh_exception.cc.
+ virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
+#endif
+ };
+#endif
+
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if _GLIBCXX_HOSTED
- // Helper for exception objects in <except>
- void
- __throw_bad_exception(void) __attribute__((__noreturn__));
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+ && __cpp_constexpr_exceptions >= 202411L)
+#if (defined(__glibcxx_exc_want_throw_bad_exception) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_exception)
+#define __glibcxx_exc_throw_bad_exception
+ // Helper for exception objects in <exception>
+ [[noreturn, __gnu__::__always_inline__]] constexpr void
+ __throw_bad_exception(void)
+ {
+ throw bad_exception();
+ }
+#endif
+
+#if (defined(__glibcxx_exc_want_throw_bad_alloc) \
+ || defined(__glibcxx_exc_want_throw_bad_array_new_length) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_alloc)
+#define __glibcxx_exc_throw_bad_alloc
+ // Helper for exception objects in <new>
+ [[noreturn, __gnu__::__always_inline__]] constexpr void
+ __throw_bad_alloc(void)
+ {
+ throw bad_alloc();
+ }
+
+ [[noreturn, __gnu__::__always_inline__]] constexpr void
+ __throw_bad_array_new_length(void)
+ {
+ throw bad_array_new_length();
+ }
+#endif
+
+#if (defined(__glibcxx_exc_want_throw_bad_cast) \
+ || defined(__glibcxx_exc_want_throw_bad_typeid) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_cast)
+#define __glibcxx_exc_throw_bad_cast
+ // Helper for exception objects in <typeinfo>
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_bad_cast(void)
+ {
+ throw bad_cast();
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_bad_typeid(void)
+ {
+ throw bad_typeid();
+ }
+#endif
+
+ // This is a complicated case. Classes like std::logic_error
+ // are defined in <stdexcept> but need std::string and <string>
+ // needs __throw_logic_error and a few others. So, for C++26
+ // constant expression we need to forward declare the constexpr
+ // __throw_logic_error etc. functions when included recursively
+ // from <string> and then at the end of that header make sure
+ // <stdexcept> is included and define those.
+ // If <string> hasn't been included yet, include it at the end
+ // of this header and that will arrange for all these to be
+ // defined.
+#if (defined(__glibcxx_exc_want_throw_logic_error) \
+ || defined(__glibcxx_exc_want_throw_domain_error) \
+ || defined(__glibcxx_exc_want_throw_invalid_argument) \
+ || defined(__glibcxx_exc_want_throw_length_error) \
+ || defined(__glibcxx_exc_want_throw_out_of_range) \
+ || defined(__glibcxx_exc_want_throw_runtime_error) \
+ || defined(__glibcxx_exc_want_throw_range_rror) \
+ || defined(__glibcxx_exc_want_throw_overflow_error) \
+ || defined(__glibcxx_exc_want_throw_underflow_error) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_logic_error) \
+ && (defined(_GLIBCXX_STRING) || __glibcxx_exc_in_string == 2)
+#ifdef __glibcxx_exc_in_string
+#ifndef __glibcxx_exc_fwd_throw_logic_error
+#define __glibcxx_exc_fwd_throw_logic_error
+ // If bits/functexcept.h is included recursively
+ // from <stdexcept> include above, just declare forward
+ // declarations.
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_logic_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_domain_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_invalid_argument(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_length_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_out_of_range(const char*);
+ template <typename... _Args>
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_out_of_range_fmt(const char* __s, _Args... __args);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_runtime_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_range_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_overflow_error(const char*);
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_underflow_error(const char*);
+#endif
+#else
+#define __glibcxx_exc_throw_logic_error
+ // Helpers for exception objects in <stdexcept>
+ namespace __detail
+ {
+ extern "C"
+ {
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt19__throw_logic_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt20__throw_domain_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt24__throw_invalid_argumentPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt20__throw_length_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt20__throw_out_of_rangePKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]]
+ [[__gnu__::__format__(__gnu_printf__, 1, 2)]] void
+ _ZSt24__throw_out_of_range_fmtPKcz(const char*, ...);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt21__throw_runtime_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt19__throw_range_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt22__throw_overflow_errorPKc(const char*);
+
+ [[noreturn, __gnu__::__cold__]] void
+ _ZSt23__throw_underflow_errorPKc(const char*);
+ }
+ } // namespace __detail
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_logic_error(const char* __s)
+ {
+ if consteval {
+ throw logic_error(__s);
+ } else {
+ __detail::_ZSt19__throw_logic_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_domain_error(const char* __s)
+ {
+ if consteval {
+ throw domain_error(__s);
+ } else {
+ __detail::_ZSt20__throw_domain_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_invalid_argument(const char* __s)
+ {
+ if consteval {
+ throw invalid_argument(__s);
+ } else {
+ __detail::_ZSt24__throw_invalid_argumentPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_length_error(const char* __s)
+ {
+ if consteval {
+ throw length_error(__s);
+ } else {
+ __detail::_ZSt20__throw_length_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_out_of_range(const char* __s)
+ {
+ if consteval {
+ throw out_of_range(__s);
+ } else {
+ __detail::_ZSt20__throw_out_of_rangePKc(__s);
+ }
+ }
+
+ template <typename... _Args>
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_out_of_range_fmt(const char* __s, _Args... __args)
+ {
+ if consteval {
+ throw out_of_range(__s);
+ } else {
+ __detail::_ZSt24__throw_out_of_range_fmtPKcz(__s, __args...);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_runtime_error(const char* __s)
+ {
+ if consteval {
+ throw runtime_error(__s);
+ } else {
+ __detail::_ZSt21__throw_runtime_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_range_error(const char* __s)
+ {
+ if consteval {
+ throw range_error(__s);
+ } else {
+ __detail::_ZSt19__throw_range_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_overflow_error(const char* __s)
+ {
+ if consteval {
+ throw overflow_error(__s);
+ } else {
+ __detail::_ZSt22__throw_overflow_errorPKc(__s);
+ }
+ }
+
+ [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+ __throw_underflow_error(const char* __s)
+ {
+ if consteval {
+ throw underflow_error(__s);
+ } else {
+ __detail::_ZSt23__throw_underflow_errorPKc(__s);
+ }
+ }
+#endif
+#endif
+#else // ! C++26 constexpr exceptions
+#if (defined(__glibcxx_exc_want_throw_bad_exception) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_exception)
+#define __glibcxx_exc_throw_bad_exception
+ // Helper for exception objects in <exception>
+ void __throw_bad_exception(void) __attribute__((__noreturn__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_bad_alloc) \
+ || defined(__glibcxx_exc_want_throw_bad_array_new_length) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_alloc)
+#define __glibcxx_exc_throw_bad_alloc
// Helper for exception objects in <new>
void
__throw_bad_alloc(void) __attribute__((__noreturn__));
void
__throw_bad_array_new_length(void) __attribute__((__noreturn__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_bad_cast) \
+ || defined(__glibcxx_exc_want_throw_bad_typeid) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_cast)
+#define __glibcxx_exc_throw_bad_cast
// Helper for exception objects in <typeinfo>
void
__throw_bad_cast(void) __attribute__((__noreturn__,__cold__));
void
__throw_bad_typeid(void) __attribute__((__noreturn__,__cold__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_logic_error) \
+ || defined(__glibcxx_exc_want_throw_domain_error) \
+ || defined(__glibcxx_exc_want_throw_invalid_argument) \
+ || defined(__glibcxx_exc_want_throw_length_error) \
+ || defined(__glibcxx_exc_want_throw_out_of_range) \
+ || defined(__glibcxx_exc_want_throw_runtime_error) \
+ || defined(__glibcxx_exc_want_throw_range_rror) \
+ || defined(__glibcxx_exc_want_throw_overflow_error) \
+ || defined(__glibcxx_exc_want_throw_underflow_error) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_logic_error)
+#define __glibcxx_exc_throw_logic_error
// Helpers for exception objects in <stdexcept>
void
__throw_logic_error(const char*) __attribute__((__noreturn__,__cold__));
@@ -93,28 +573,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
__throw_underflow_error(const char*) __attribute__((__noreturn__,__cold__));
+#endif
+#endif // ! C++26 constexpr exceptions
- // Helpers for exception objects in <ios>
+#if (defined(__glibcxx_exc_want_throw_ios_failure) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_ios_failure)
+#define __glibcxx_exc_throw_ios_failure
+// Helpers for exception objects in <ios>
void
__throw_ios_failure(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_ios_failure(const char*, int) __attribute__((__noreturn__,__cold__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_system_error) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_system_error)
+#define __glibcxx_exc_throw_system_error
// Helpers for exception objects in <system_error>
void
__throw_system_error(int) __attribute__((__noreturn__,__cold__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_future_error) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_future_error)
+#define __glibcxx_exc_throw_future_error
// Helpers for exception objects in <future>
void
__throw_future_error(int) __attribute__((__noreturn__,__cold__));
+#endif
+#if (defined(__glibcxx_exc_want_throw_bad_function_call) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_bad_function_call)
+#define __glibcxx_exc_throw_bad_function_call
// Helpers for exception objects in <functional>
void
__throw_bad_function_call() __attribute__((__noreturn__,__cold__));
+#endif
#else // ! HOSTED
+#if (defined(__glibcxx_exc_want_throw_logic_error) \
+ || defined(__glibcxx_exc_want_throw_domain_error) \
+ || defined(__glibcxx_exc_want_throw_invalid_argument) \
+ || defined(__glibcxx_exc_want_throw_length_error) \
+ || defined(__glibcxx_exc_want_throw_out_of_range) \
+ || defined(__glibcxx_exc_want_throw_runtime_error) \
+ || defined(__glibcxx_exc_want_throw_range_rror) \
+ || defined(__glibcxx_exc_want_throw_overflow_error) \
+ || defined(__glibcxx_exc_want_throw_underflow_error) \
+ || defined(__glibcxx_exc_want_throw_all)) \
+ && !defined(__glibcxx_exc_throw_logic_error)
+#define __glibcxx_exc_throw_logic_error
__attribute__((__noreturn__)) inline void
__throw_invalid_argument(const char*)
{ std::__terminate(); }
@@ -134,10 +648,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__attribute__((__noreturn__)) inline void
__throw_overflow_error(const char*)
{ std::__terminate(); }
+#endif
#endif // HOSTED
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
+}
+#endif
+
+#undef __glibcxx_exc_want_throw_all
+#undef __glibcxx_exc_want_throw_bad_exception
+#undef __glibcxx_exc_want_throw_bad_alloc
+#undef __glibcxx_exc_want_throw_bad_array_new_length
+#undef __glibcxx_exc_want_throw_bad_cast
+#undef __glibcxx_exc_want_throw_bad_typeid
+#undef __glibcxx_exc_want_throw_logic_error
+#undef __glibcxx_exc_want_throw_domain_error
+#undef __glibcxx_exc_want_throw_invalid_argument
+#undef __glibcxx_exc_want_throw_length_error
+#undef __glibcxx_exc_want_throw_out_of_range
+#undef __glibcxx_exc_want_throw_runtime_error
+#undef __glibcxx_exc_want_throw_range_rror
+#undef __glibcxx_exc_want_throw_overflow_error
+#undef __glibcxx_exc_want_throw_underflow_error
+#undef __glibcxx_exc_want_throw_ios_failure
+#undef __glibcxx_exc_want_throw_system_error
+#undef __glibcxx_exc_want_throw_future_error
+#undef __glibcxx_exc_want_throw_bad_function_call
+#undef __glibcxx_exc_want_exception
+#undef __glibcxx_exc_want_new
+#undef __glibcxx_exc_want_typeinfo
+
+#if defined(__glibcxx_exc_want_stdexcept) \
+ && !defined(_GLIBCXX_STRING) \
+ && __glibcxx_exc_in_string != 2
+#undef __glibcxx_exc_want_stdexcept
+#include <string>
#endif
+#undef __glibcxx_exc_want_stdexcept
--- libstdc++-v3/include/bits/stl_map.h.jj 2025-08-12 18:31:42.164614425 +0200
+++ libstdc++-v3/include/bits/stl_map.h 2025-08-12 18:32:56.414661485 +0200
@@ -56,6 +56,7 @@
#ifndef _STL_MAP_H
#define _STL_MAP_H 1
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
#include <bits/concept_check.h>
#if __cplusplus >= 201103L
--- libstdc++-v3/include/bits/locale_classes.h.jj 2025-08-12 18:31:42.158614502 +0200
+++ libstdc++-v3/include/bits/locale_classes.h 2025-08-12 18:32:56.416661460 +0200
@@ -38,6 +38,9 @@
#pragma GCC system_header
#endif
+#define __glibcxx_exc_want_throw_bad_cast
+#define __glibcxx_exc_want_throw_system_error
+#include <bits/functexcept.h>
#include <bits/localefwd.h>
#include <string>
#include <ext/atomicity.h>
--- libstdc++-v3/include/bits/hashtable_policy.h.jj 2025-08-12 18:31:42.157614514 +0200
+++ libstdc++-v3/include/bits/hashtable_policy.h 2025-08-12 18:32:56.417661447 +0200
@@ -32,6 +32,8 @@
#define _HASHTABLE_POLICY_H 1
#include <tuple> // for std::tuple, std::forward_as_tuple
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
#include <bits/functional_hash.h> // for __is_fast_hash
#include <bits/stl_algobase.h> // for std::min
#include <bits/stl_pair.h> // for std::pair
--- libstdc++-v3/include/bits/std_function.h.jj 2025-08-12 18:31:42.160614476 +0200
+++ libstdc++-v3/include/bits/std_function.h 2025-08-12 18:32:56.416661460 +0200
@@ -42,6 +42,7 @@
#include <typeinfo> // typeid
#include <bits/invoke.h> // __invoke_r
#include <bits/refwrap.h> // ref wrapper, _Maybe_unary_or_binary_function
+#define __glibcxx_exc_want_throw_bad_function_call
#include <bits/functexcept.h> // __throw_bad_function_call
namespace std _GLIBCXX_VISIBILITY(default)
--- libstdc++-v3/include/bits/formatfwd.h.jj 2025-08-12 18:31:42.154614553 +0200
+++ libstdc++-v3/include/bits/formatfwd.h 2025-08-12 18:32:56.415661472 +0200
@@ -56,11 +56,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [format.formatter], formatter
template<typename _Tp, typename _CharT = char> struct formatter;
-/// @cond undocumented
- [[noreturn]]
- inline void
- __throw_format_error(const char* __what);
-
namespace __format
{
#ifdef _GLIBCXX_USE_WCHAR_T
--- libstdc++-v3/include/bits/specfun.h.jj 2025-08-12 18:31:42.160614476 +0200
+++ libstdc++-v3/include/bits/specfun.h 2025-08-12 18:32:56.415661472 +0200
@@ -40,6 +40,9 @@
# error include <cmath> and define __STDCPP_WANT_MATH_SPEC_FUNCS__
#endif
+#define __glibcxx_exc_want_throw_domain_error
+#define __glibcxx_exc_want_throw_runtime_error
+#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <limits>
#include <type_traits>
--- libstdc++-v3/include/bits/basic_ios.h.jj 2025-08-12 18:31:42.153614566 +0200
+++ libstdc++-v3/include/bits/basic_ios.h 2025-08-12 18:32:56.414661485 +0200
@@ -34,6 +34,9 @@
#pragma GCC system_header
#endif
+#define __glibcxx_exc_want_throw_bad_cast
+#define __glibcxx_exc_want_throw_ios_failure
+#include <bits/functexcept.h>
#include <bits/localefwd.h>
#include <bits/locale_classes.h>
#include <bits/locale_facets.h>
--- libstdc++-v3/include/bits/std_thread.h.jj 2025-08-12 18:31:42.161614463 +0200
+++ libstdc++-v3/include/bits/std_thread.h 2025-08-12 18:32:56.415661472 +0200
@@ -48,6 +48,7 @@
# include <bits/gthr.h>
#else
# include <errno.h>
+# define __glibcxx_exc_want_throw_system_error
# include <bits/functexcept.h>
#endif
--- libstdc++-v3/include/tr1/cmath.jj 2025-08-12 18:31:42.185614155 +0200
+++ libstdc++-v3/include/tr1/cmath 2025-08-12 18:32:56.418661434 +0200
@@ -34,6 +34,9 @@
#endif
#include <bits/requires_hosted.h> // TR1
+#define __glibcxx_exc_want_throw_domain_error
+#define __glibcxx_exc_want_throw_runtime_error
+#include <bits/functexcept.h>
#include <cmath>
--- libstdc++-v3/include/tr1/memory.jj 2025-08-12 18:31:42.185614155 +0200
+++ libstdc++-v3/include/tr1/memory 2025-08-12 18:32:56.417661447 +0200
@@ -47,7 +47,6 @@
#include <iosfwd> // std::basic_ostream
#include <ext/atomicity.h>
#include <ext/concurrence.h>
-#include <bits/functexcept.h>
#include <bits/stl_function.h> // std::less
#include <debug/debug.h>
#include <tr1/type_traits>
--- libstdc++-v3/include/tr1/array.jj 2025-08-12 18:31:42.183614181 +0200
+++ libstdc++-v3/include/tr1/array 2025-08-12 18:32:56.418661434 +0200
@@ -34,6 +34,8 @@
#endif
#include <bits/requires_hosted.h> // TR1
+#define __glibcxx_exc_want_throw_out_of_range
+#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
--- libstdc++-v3/include/ext/vstring_util.h.jj 2025-08-12 18:31:42.175614284 +0200
+++ libstdc++-v3/include/ext/vstring_util.h 2025-08-12 18:32:56.420661408 +0200
@@ -39,6 +39,9 @@
#include <ext/vstring_fwd.h>
#include <debug/debug.h>
#include <bits/stl_function.h> // For less
+#define __glibcxx_exc_want_throw_length_error
+#define __glibcxx_exc_want_throw_logic_error
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
#include <bits/localefwd.h>
#include <bits/ostream_insert.h>
--- libstdc++-v3/include/ext/bitmap_allocator.h.jj 2025-08-12 18:31:42.168614373 +0200
+++ libstdc++-v3/include/ext/bitmap_allocator.h 2025-08-12 18:32:56.419661421 +0200
@@ -32,6 +32,7 @@
#include <bits/requires_hosted.h> // GNU extensions are currently omitted
#include <utility> // For std::pair.
+#define __glibcxx_exc_want_throw_bad_alloc
#include <bits/functexcept.h> // For __throw_bad_alloc().
#include <bits/stl_function.h> // For greater_equal, and less_equal.
#include <new> // For operator new.
--- libstdc++-v3/include/ext/mt_allocator.h.jj 2025-08-12 18:31:42.169614361 +0200
+++ libstdc++-v3/include/ext/mt_allocator.h 2025-08-12 18:32:56.419661421 +0200
@@ -33,6 +33,7 @@
#include <new>
#include <cstdlib>
+#define __glibcxx_exc_want_throw_bad_alloc
#include <bits/functexcept.h>
#include <ext/atomicity.h>
#include <bits/move.h>
--- libstdc++-v3/include/ext/malloc_allocator.h.jj 2025-08-12 18:31:42.168614373 +0200
+++ libstdc++-v3/include/ext/malloc_allocator.h 2025-08-12 18:32:56.420661408 +0200
@@ -34,6 +34,8 @@
#include <cstdlib>
#include <cstddef>
#include <new>
+#define __glibcxx_exc_want_throw_bad_alloc
+#define __glibcxx_exc_want_throw_bad_array_new_length
#include <bits/functexcept.h>
#include <bits/move.h>
#if __cplusplus >= 201103L
--- libstdc++-v3/include/ext/debug_allocator.h.jj 2025-08-12 18:31:42.168614373 +0200
+++ libstdc++-v3/include/ext/debug_allocator.h 2025-08-12 18:32:56.419661421 +0200
@@ -45,6 +45,7 @@
#include <bits/requires_hosted.h> // GNU extensions are currently omitted
#include <stdexcept>
+#define __glibcxx_exc_want_throw_runtime_error
#include <bits/functexcept.h>
#include <ext/alloc_traits.h>
--- libstdc++-v3/include/ext/concurrence.h.jj 2025-08-12 18:31:42.168614373 +0200
+++ libstdc++-v3/include/ext/concurrence.h 2025-08-12 18:32:56.419661421 +0200
@@ -35,7 +35,7 @@
#include <exception>
#include <bits/gthr.h>
-#include <bits/functexcept.h>
+#include <bits/exception_defines.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
--- libstdc++-v3/include/ext/throw_allocator.h.jj 2025-08-12 18:31:42.172614322 +0200
+++ libstdc++-v3/include/ext/throw_allocator.h 2025-08-12 18:32:56.418661434 +0200
@@ -55,6 +55,9 @@
#include <ostream>
#include <stdexcept>
#include <utility>
+#define __glibcxx_exc_want_throw_logic_error
+#define __glibcxx_exc_want_throw_out_of_range
+#define __glibcxx_exc_want_throw_bad_alloc
#include <bits/functexcept.h>
#include <bits/move.h>
#if __cplusplus >= 201103L
--- libstdc++-v3/include/ext/string_conversions.h.jj 2025-08-12 18:31:42.171614335 +0200
+++ libstdc++-v3/include/ext/string_conversions.h 2025-08-12 18:32:56.419661421 +0200
@@ -41,6 +41,8 @@
#include <bits/c++config.h>
#include <ext/numeric_traits.h>
+#define __glibcxx_exc_want_throw_invalid_argument
+#define __glibcxx_exc_want_throw_out_of_range
#include <bits/functexcept.h>
#include <cstdlib>
#include <cwchar>
--- libstdc++-v3/include/ext/pool_allocator.h.jj 2025-08-12 18:31:42.170614348 +0200
+++ libstdc++-v3/include/ext/pool_allocator.h 2025-08-12 18:32:56.418661434 +0200
@@ -47,6 +47,7 @@
#include <bits/c++config.h>
#include <cstdlib>
#include <new>
+#define __glibcxx_exc_want_throw_bad_alloc
#include <bits/functexcept.h>
#include <ext/atomicity.h>
#include <ext/concurrence.h>
--- libstdc++-v3/include/ext/ropeimpl.h.jj 2025-08-12 18:31:42.171614335 +0200
+++ libstdc++-v3/include/ext/ropeimpl.h 2025-08-12 18:32:56.419661421 +0200
@@ -42,6 +42,7 @@
#include <cstdio>
#include <ostream>
+#define __glibcxx_exc_want_throw_length_error
#include <bits/functexcept.h>
#include <ext/algorithm> // For copy_n and lexicographical_compare_3way
--- libstdc++-v3/include/tr2/dynamic_bitset.jj 2025-08-12 18:31:42.186614142 +0200
+++ libstdc++-v3/include/tr2/dynamic_bitset 2025-08-12 18:32:56.420661408 +0200
@@ -37,6 +37,9 @@
#include <vector>
#include <string>
#include <istream>
+#define __glibcxx_exc_want_throw_out_of_range
+#define __glibcxx_exc_want_throw_overflow_error
+#define __glibcxx_exc_want_throw_invalid_argument
#include <bits/functexcept.h>
#include <bits/stl_algo.h> // For fill
#include <bits/cxxabi_forced.h>
--- libstdc++-v3/include/experimental/optional.jj 2025-08-12 18:31:42.167614386 +0200
+++ libstdc++-v3/include/experimental/optional 2025-08-12 18:32:56.420661408 +0200
@@ -38,7 +38,7 @@
#include <stdexcept>
#include <new>
#include <initializer_list>
-#include <bits/functexcept.h>
+#include <bits/exception_defines.h>
#include <bits/functional_hash.h>
#include <bits/enable_special_members.h>
#include <bits/move.h>
--- libstdc++-v3/include/Makefile.am.jj 2025-08-12 18:31:42.151614591 +0200
+++ libstdc++-v3/include/Makefile.am 2025-08-12 18:32:56.418661434 +0200
@@ -260,6 +260,7 @@ bits_headers = \
${bits_srcdir}/std_function.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/std_thread.h \
+ ${bits_srcdir}/stdexcept.h \
${bits_srcdir}/stl_bvector.h \
${bits_srcdir}/stl_deque.h \
${bits_srcdir}/stl_list.h \
--- libstdc++-v3/include/Makefile.in.jj 2025-08-12 18:31:42.152614579 +0200
+++ libstdc++-v3/include/Makefile.in 2025-08-12 18:32:56.413661498 +0200
@@ -613,6 +613,7 @@ bits_freestanding = \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/std_function.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/std_mutex.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/std_thread.h \
+@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/stdexcept.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/stl_bvector.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/stl_deque.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/stl_list.h \
--- libstdc++-v3/src/c++20/atomic.cc.jj 2025-08-12 18:31:42.193614053 +0200
+++ libstdc++-v3/src/c++20/atomic.cc 2025-08-12 18:32:56.420661408 +0200
@@ -36,6 +36,7 @@
# include <climits>
# include <unistd.h>
# include <syscall.h>
+# define __glibcxx_exc_want_throw_all
# include <bits/functexcept.h>
# include <sys/time.h>
#endif
--- libstdc++-v3/src/c++17/floating_from_chars.cc.jj 2025-08-12 18:31:42.192614065 +0200
+++ libstdc++-v3/src/c++17/floating_from_chars.cc 2025-08-12 18:32:56.421661395 +0200
@@ -45,6 +45,7 @@
#include <cstdlib>
#include <cstring>
#include <locale.h>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
#if _GLIBCXX_HAVE_XLOCALE_H
# include <xlocale.h>
--- libstdc++-v3/src/c++11/system_error.cc.jj 2025-08-12 18:31:42.192614065 +0200
+++ libstdc++-v3/src/c++11/system_error.cc 2025-08-12 18:32:56.421661395 +0200
@@ -27,6 +27,7 @@
#define __sso_string __sso_stringxxx
#include <cstring>
#include <system_error>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
#include <limits>
#include <errno.h>
--- libstdc++-v3/src/c++11/regex.cc.jj 2025-08-12 18:31:42.191614078 +0200
+++ libstdc++-v3/src/c++11/regex.cc 2025-08-12 18:32:56.421661395 +0200
@@ -24,6 +24,7 @@
#include <stdexcept>
#include <bits/regex_error.h>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
namespace std _GLIBCXX_VISIBILITY(default)
--- libstdc++-v3/src/c++11/cxx11-ios_failure.cc.jj 2025-08-12 18:31:42.189614104 +0200
+++ libstdc++-v3/src/c++11/cxx11-ios_failure.cc 2025-08-12 18:32:56.421661395 +0200
@@ -28,6 +28,7 @@
#define _GLIBCXX_USE_CXX11_ABI 1
#include <ios>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
#include <cxxabi.h>
--- libstdc++-v3/src/c++11/functexcept.cc.jj 2025-08-12 18:31:42.189614104 +0200
+++ libstdc++-v3/src/c++11/functexcept.cc 2025-08-12 18:32:56.422661382 +0200
@@ -20,6 +20,7 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
#include <cstdlib>
#include <exception>
--- libstdc++-v3/src/c++11/snprintf_lite.cc.jj 2025-08-12 18:31:42.191614078 +0200
+++ libstdc++-v3/src/c++11/snprintf_lite.cc 2025-08-12 18:32:56.421661395 +0200
@@ -25,6 +25,7 @@
#include <stdarg.h>
#include <stddef.h>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
namespace __gnu_cxx {
--- libstdc++-v3/src/c++11/future.cc.jj 2025-08-12 18:31:42.190614091 +0200
+++ libstdc++-v3/src/c++11/future.cc 2025-08-12 18:32:56.421661395 +0200
@@ -23,6 +23,7 @@
// <http://www.gnu.org/licenses/>.
#include <future>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
#if __has_cpp_attribute(clang::require_constant_initialization)
--- libstdc++-v3/src/c++11/thread.cc.jj 2025-01-02 20:54:32.930118834 +0100
+++ libstdc++-v3/src/c++11/thread.cc 2025-08-12 19:16:34.972087396 +0200
@@ -30,6 +30,8 @@
#include <system_error>
#include <cerrno>
#include <cxxabi_forced.h>
+#define __glibcxx_exc_want_throw_system_error
+#include <bits/functexcept.h>
#ifndef _GLIBCXX_USE_NANOSLEEP
# ifdef _GLIBCXX_HAVE_SLEEP
--- libstdc++-v3/src/c++11/functional.cc.jj 2025-08-12 18:31:42.190614091 +0200
+++ libstdc++-v3/src/c++11/functional.cc 2025-08-12 18:32:56.421661395 +0200
@@ -23,6 +23,7 @@
// <http://www.gnu.org/licenses/>.
#include <functional>
+#define __glibcxx_exc_want_throw_all
#include <bits/functexcept.h>
namespace std _GLIBCXX_VISIBILITY(default)
--- libstdc++-v3/testsuite/util/testsuite_shared.cc.jj 2025-08-12 18:31:42.199613976 +0200
+++ libstdc++-v3/testsuite/util/testsuite_shared.cc 2025-08-12 18:32:56.422661382 +0200
@@ -22,6 +22,7 @@
#include <set>
#include <map>
#include <ext/mt_allocator.h>
+#define __glibcxx_exc_want_throw_bad_exception
#include <bits/functexcept.h>
#if __cpp_rtti
# include <typeinfo>
--- libstdc++-v3/testsuite/util/testsuite_hooks.h.jj 2025-08-12 18:31:42.199613976 +0200
+++ libstdc++-v3/testsuite/util/testsuite_hooks.h 2025-08-12 18:32:56.422661382 +0200
@@ -44,6 +44,7 @@
#define _GLIBCXX_TESTSUITE_HOOKS_H
#include <bits/c++config.h>
+#define __glibcxx_exc_want_throw_runtime_error
#include <bits/functexcept.h>
#include <ctime>
#include <stdio.h>
--- libstdc++-v3/testsuite/util/io/verified_cmd_line_input.cc.jj 2025-08-12 18:31:42.198613988 +0200
+++ libstdc++-v3/testsuite/util/io/verified_cmd_line_input.cc 2025-08-12 18:32:56.422661382 +0200
@@ -38,7 +38,7 @@
#include <limits.h>
#include <utility>
#include <stdlib.h>
-#include <bits/functexcept.h>
+#include <bits/exception_defines.h>
namespace __gnu_pbds
{
--- libstdc++-v3/testsuite/20_util/allocator/105975.cc.jj 2023-09-19 19:47:23.988430017 +0200
+++ libstdc++-v3/testsuite/20_util/allocator/105975.cc 2025-08-13 10:47:30.213212151 +0200
@@ -9,10 +9,11 @@ consteval bool test_pr105957()
{
std::allocator<long long> a;
auto n = std::size_t(-1) / (sizeof(long long) - 1);
- auto p = a.allocate(n); // { dg-error "constexpr" }
+ auto p = a.allocate(n); // { dg-error "constexpr" "" { target c++23_down } }
a.deallocate(p, n);
return true;
}
static_assert( test_pr105957() ); // { dg-error "non-constant" }
+// { dg-error "uncaught exception of type 'std::bad_array_new_length'" "" { target c++26 } 16 }
-// { dg-error "throw_bad_array_new_length" "" { target *-*-* } 0 }
+// { dg-error "throw_bad_array_new_length" "" { target c++23_down } 0 }
--- libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc.jj 2025-07-15 14:49:29.977515400 +0200
+++ libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc 2025-08-13 10:40:25.409793713 +0200
@@ -26,6 +26,6 @@ int n1 = std::get<1>(a);
int n2 = std::get<1>(std::move(a));
int n3 = std::get<1>(ca);
-// { dg-error "static assertion failed" "" { target *-*-* } 396 }
-// { dg-error "static assertion failed" "" { target *-*-* } 405 }
-// { dg-error "static assertion failed" "" { target *-*-* } 414 }
+// { dg-error "static assertion failed" "" { target *-*-* } 397 }
+// { dg-error "static assertion failed" "" { target *-*-* } 406 }
+// { dg-error "static assertion failed" "" { target *-*-* } 415 }
--- libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc.jj 2025-07-19 14:39:32.617034910 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc 2025-08-13 10:33:48.952002827 +0200
@@ -20,12 +20,11 @@ test_reserve()
v.reserve(N);
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
--- libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc.jj 2025-07-27 17:19:23.688126964 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc 2025-08-13 10:48:17.362597972 +0200
@@ -14,12 +14,11 @@ test_out_of_capacity()
std::inplace_vector<T, N> v;
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
@@ -82,12 +81,11 @@ test_access()
VERIFY( e4a == T(5) );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
--- libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc.jj 2025-07-19 14:39:32.000000000 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc 2025-08-13 10:57:26.188487208 +0200
@@ -164,10 +164,9 @@ test_n()
VERIFY( z0.begin() == z0.end() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if not consteval {
+#endif
try
{
std::inplace_vector<int, 2> ct(3);
@@ -186,8 +185,10 @@ test_n()
{
}
+#ifndef __cpp_lib_constexpr_exceptions
}
#endif
+#endif
#ifdef __cpp_lib_constexpr_inplace_vector
#error remove the consteval check
@@ -241,10 +242,9 @@ test_n_val()
VERIFY( z0.begin() == z0.end() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if not consteval {
+#endif
try
{
std::inplace_vector<int, 2> ct(3, 11);
@@ -262,8 +262,10 @@ test_n_val()
catch (std::bad_alloc const&)
{
}
+#ifndef __cpp_lib_constexpr_exceptions
}
#endif
+#endif
#ifdef __cpp_lib_constexpr_inplace_vector
#error remove the consteval check
@@ -317,10 +319,9 @@ test_initializer_list()
VERIFY( z0.begin() == z0.end() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if not consteval {
+#endif
try
{
std::inplace_vector<int, 2> ct{11, 22, 33};
@@ -338,8 +339,10 @@ test_initializer_list()
catch (std::bad_alloc const&)
{
}
+#ifndef __cpp_lib_constexpr_exceptions
}
#endif
+#endif
#ifdef __cpp_lib_constexpr_inplace_vector
#error remove the consteval check
--- libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc.jj 2025-07-27 17:19:23.688126964 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc 2025-08-13 10:48:42.293274962 +0200
@@ -41,12 +41,11 @@ do_test_it()
VERIFY( eq<T>(v4, {a, 4}) );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
bounds = typename It::ContainerType(a, a+9);
try
@@ -104,12 +103,11 @@ do_test_r()
VERIFY( eq<T>(v4, {a, 4}) );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
--- libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc.jj 2025-07-19 14:39:32.618034897 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc 2025-08-13 10:32:49.651781980 +0200
@@ -48,12 +48,11 @@ test_add_to_full()
VERIFY( eq<T>(v, {a, N}) );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
--- libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc.jj 2025-07-27 17:19:23.000000000 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc 2025-08-13 10:49:04.114992233 +0200
@@ -60,12 +60,11 @@ test_assign_empty_it()
VERIFY( v.empty() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
static_assert(N < 9);
@@ -136,12 +135,11 @@ test_assign_empty_other()
VERIFY( v.empty() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
static_assert(N < 9);
--- libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc.jj 2025-07-27 17:19:23.689126952 +0200
+++ libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc 2025-08-13 10:50:05.423197903 +0200
@@ -105,12 +105,11 @@ test_add_to_full_it()
VERIFY( rit4.base() == a+2 );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
@@ -191,12 +190,11 @@ test_add_to_full_other()
VERIFY( it == v.begin() );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
v = std::inplace_vector<T, N>(std::from_range, std::span(a, a+N));
try
@@ -249,12 +247,11 @@ test_append_range()
VERIFY( eq<T>(v, {a, 15}) );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
@@ -313,12 +310,11 @@ test_insert_range()
VERIFY( it == v.begin() + 5 );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
const bool seg = std::ranges::sized_range<Range> || std::ranges::forward_range<Range>;
auto vc = v;
@@ -390,12 +386,11 @@ test_insert_iterators()
VERIFY( it == v.begin() + 5 );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
const bool seg = std::forward_iterator<It>;
auto vc = v;
@@ -457,12 +452,11 @@ test_insert_initializer_list()
VERIFY( it == v.begin() + 5 );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
std::initializer_list<T> il
= {T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9)};
@@ -520,12 +514,11 @@ test_insert_repeated()
VERIFY( it == v.begin() + 5 );
#ifdef __cpp_exceptions
-#ifdef __cpp_lib_constexpr_exceptions
-#error remove the consteval check
-#endif
+#ifndef __cpp_lib_constexpr_exceptions
if consteval {
return;
}
+#endif
try
{
--- libstdc++-v3/libsupc++/exception.jj 2025-08-12 18:31:42.187614129 +0200
+++ libstdc++-v3/libsupc++/exception 2025-08-12 19:11:53.844690112 +0200
@@ -41,6 +41,8 @@
#define __glibcxx_want_constexpr_exceptions
#define __glibcxx_want_exception_ptr_cast
#include <bits/version.h>
+#define __glibcxx_exc_want_exception
+#include <bits/functexcept.h>
extern "C++" {
@@ -50,34 +52,6 @@ namespace std _GLIBCXX_VISIBILITY(defaul
* @{
*/
- /** If an %exception is thrown which is not listed in a function's
- * %exception specification, one of these may be thrown.
- *
- * @ingroup exceptions
- */
- class bad_exception : public exception
- {
- public:
- _GLIBCXX26_CONSTEXPR bad_exception() _GLIBCXX_USE_NOEXCEPT { }
-
-#if __cplusplus >= 202400L
- constexpr virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
-
- constexpr virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN noexcept
- {
- return "std::bad_exception";
- }
-#else
- // This declaration is not useless:
- // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
- virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
-
- // See comment in eh_exception.cc.
- virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
-#endif
- };
-
/// If you write a replacement %terminate handler, it must be of this type.
typedef void (*terminate_handler) ();
--- libstdc++-v3/libsupc++/new.jj 2025-08-12 18:31:42.188614117 +0200
+++ libstdc++-v3/libsupc++/new 2025-08-12 18:32:56.424661357 +0200
@@ -47,6 +47,8 @@
#define __glibcxx_want_destroying_delete
#define __glibcxx_want_constexpr_new
#include <bits/version.h>
+#define __glibcxx_exc_want_new
+#include <bits/functexcept.h> // std::bad_alloc, std::bad_array_new_length
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++11-extensions" // scoped enum
@@ -57,63 +59,6 @@ extern "C++" {
namespace std
{
- /**
- * @brief Exception possibly thrown by @c new.
- * @ingroup exceptions
- *
- * @c bad_alloc (or classes derived from it) is used to report allocation
- * errors from the throwing forms of @c new. */
- class bad_alloc : public exception
- {
- public:
- _GLIBCXX26_CONSTEXPR bad_alloc() throw() { }
-
-#if __cplusplus >= 201103L
- _GLIBCXX26_CONSTEXPR bad_alloc(const bad_alloc&) = default;
- _GLIBCXX26_CONSTEXPR bad_alloc& operator=(const bad_alloc&) = default;
-#endif
-
-#if __cplusplus >= 202400L
- constexpr virtual ~bad_alloc() noexcept {}
-
- constexpr virtual const char* what() const noexcept
- {
- return "std::bad_alloc";
- }
-#else
- // This declaration is not useless:
- // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
- virtual ~bad_alloc() throw();
-
- // See comment in eh_exception.cc.
- virtual const char* what() const throw();
-#endif
- };
-
-#if __cplusplus >= 201103L
- class bad_array_new_length : public bad_alloc
- {
- public:
- _GLIBCXX26_CONSTEXPR bad_array_new_length() throw() { }
-
-#if __cplusplus >= 202400L
- constexpr virtual ~bad_array_new_length() noexcept {}
-
- constexpr virtual const char* what() const noexcept
- {
- return "std::bad_array_new_length";
- }
-#else
- // This declaration is not useless:
- // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
- virtual ~bad_array_new_length() throw();
-
- // See comment in eh_exception.cc.
- virtual const char* what() const throw();
-#endif
- };
-#endif
-
#if __cpp_aligned_new
enum class align_val_t: size_t {};
#endif
--- libstdc++-v3/libsupc++/typeinfo.jj 2025-08-12 18:31:42.188614117 +0200
+++ libstdc++-v3/libsupc++/typeinfo 2025-08-12 18:32:56.423661370 +0200
@@ -40,6 +40,8 @@
#define __glibcxx_want_constexpr_typeinfo
#include <bits/version.h>
+#define __glibcxx_exc_want_typeinfo
+#include <bits/functexcept.h> // std::bad_cast, std::bad_typeid
#pragma GCC visibility push(default)
@@ -213,61 +215,6 @@ namespace std
#endif
}
#endif
-
-
- /**
- * @brief Thrown during incorrect typecasting.
- * @ingroup exceptions
- *
- * If you attempt an invalid @c dynamic_cast expression, an instance of
- * this class (or something derived from this class) is thrown. */
- class bad_cast : public exception
- {
- public:
- _GLIBCXX26_CONSTEXPR bad_cast() _GLIBCXX_USE_NOEXCEPT { }
-
-#if __cplusplus >= 202400L
- constexpr virtual ~bad_cast() noexcept {}
-
- constexpr virtual const char* what() const noexcept
- {
- return "std::bad_cast";
- }
-#else
- // This declaration is not useless:
- // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
- virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT;
-
- // See comment in eh_exception.cc.
- virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
-#endif
- };
-
- /**
- * @brief Thrown when a NULL pointer in a @c typeid expression is used.
- * @ingroup exceptions
- */
- class bad_typeid : public exception
- {
- public:
- _GLIBCXX26_CONSTEXPR bad_typeid () _GLIBCXX_USE_NOEXCEPT { }
-
-#if __cplusplus >= 202400L
- constexpr virtual ~bad_typeid() noexcept {}
-
- constexpr virtual const char* what() const noexcept
- {
- return "std::bad_typeid";
- }
-#else
- // This declaration is not useless:
- // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
- virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT;
-
- // See comment in eh_exception.cc.
- virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
-#endif
- };
} // namespace std
} // extern "C++"
--- libgomp/omp.h.in.jj 2025-06-02 21:58:22.142775820 +0200
+++ libgomp/omp.h.in 2025-08-13 09:46:19.094406599 +0200
@@ -439,6 +439,8 @@ extern const char *omp_get_uid_from_devi
#if __cplusplus >= 201103L
/* std::__throw_bad_alloc and std::__throw_bad_array_new_length. */
+#define __glibcxx_exc_want_throw_bad_alloc
+#define __glibcxx_exc_want_throw_bad_array_new_length
#include <bits/functexcept.h>
namespace omp
--- gcc/testsuite/g++.dg/tree-ssa/pr110819.C.jj 2024-11-18 21:59:35.957149081 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr110819.C 2025-08-13 11:10:01.834625390 +0200
@@ -11,4 +11,5 @@ void use_idx_const_size_reserve() {
for (std::vector<int>::size_type i = 0; i < s; i++)
f(v[i]);
}
-// { dg-final { scan-tree-dump-not "delete" "optimized" } }
+// For C++26 delete appears in ~bad_array() and ~bad_array_new_length() dtors.
+// { dg-final { scan-tree-dump-not "delete" "optimized" { target c++23_down } } }
--- gcc/testsuite/g++.dg/tree-ssa/pr96945.C.jj 2024-11-18 21:59:35.957149081 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr96945.C 2025-08-13 11:10:08.636536892 +0200
@@ -57,4 +57,5 @@ struct c7 {
void foo7(){
std::vector<c7> vi = {c7(),c7(),c7()};
}
-// { dg-final { scan-tree-dump-not "delete" "optimized" } }
+// For C++26 delete appears in ~bad_array() and ~bad_array_new_length() dtors.
+// { dg-final { scan-tree-dump-not "delete" "optimized" { target c++23_down } } }
--- gcc/testsuite/g++.dg/tree-ssa/pr109442.C.jj 2024-11-18 21:59:35.957149081 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr109442.C 2025-08-13 11:10:14.046466502 +0200
@@ -9,4 +9,5 @@ T vat1(std::vector<T> v1) {
// This should compile to empty function; check that no size of
// vector is determined and there is no allocation
// { dg-final { scan-tree-dump-not "_M_start" "optimized" } }
-// { dg-final { scan-tree-dump-not "delete" "optimized" } }
+// For C++26 delete appears in ~bad_array() and ~bad_array_new_length() dtors.
+// { dg-final { scan-tree-dump-not "delete" "optimized" { target c++23_down } } }
--- gcc/testsuite/g++.dg/tree-ssa/pr116868.C.jj 2024-11-18 21:59:35.957149081 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr116868.C 2025-08-13 11:10:18.179412734 +0200
@@ -9,4 +9,5 @@ int sumVector() {
}
return sum;
}
-// { dg-final { scan-tree-dump-not "delete" "optimized" } }
+// For C++26 delete appears in ~bad_array() and ~bad_array_new_length() dtors.
+// { dg-final { scan-tree-dump-not "delete" "optimized" { target c++23_down } } }
--- gcc/testsuite/g++.dg/tree-ssa/pr58483.C.jj 2024-11-18 21:59:35.957149081 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr58483.C 2025-08-13 11:10:21.539369019 +0200
@@ -11,4 +11,5 @@ void use_idx_const_size_reserve() {
for (std::vector<int>::size_type i = 0; i < s; i++)
f(v[i]);
}
-// { dg-final { scan-tree-dump-not "delete" "optimized" } }
+// For C++26 delete appears in ~bad_array() and ~bad_array_new_length() dtors.
+// { dg-final { scan-tree-dump-not "delete" "optimized" { target c++23_down } } }
Jakub
More information about the Libstdc++
mailing list