]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement C++26 P3378R2 - constexpr exception types
authorJakub Jelinek <jakub@redhat.com>
Thu, 11 Dec 2025 18:37:22 +0000 (19:37 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 11 Dec 2025 18:54:44 +0000 (19:54 +0100)
The following patch attempts to implement the C++26 P3378R2 - constexpr
exception types paper.

This is quite complicated, because most of these classes which should
be constexpr-ized use solely or mostly out of line definitions in
libstdc++, both for historical, code size and dual ABI reasons, so that
one can throw these as exceptions between TUs with old vs. new (or vice
versa) ABIs.
For this reason, logic_error/runtime_error and classes derived from it
have the old ABI std::string object inside of them and the exported
APIs from libstdc++.so.6 ensure the right thing.

Now, because new invoked during constant evaluation needs to be deleted
during the same constant evaluation and can't leak into the constant
expressions, I think we don't have to use COW strings under the hood
(which aren't constexpr I guess because of reference counting/COW) and
we can use something else, the patch uses heap allocated std::string
object (where __cow_constexpr_string class has just a pointer to that).
As I think we still want to hide the ugly details if !consteval in the
library, the patch exports 8 __cow_string class symbols (6 existing which
were previously just not exported and 2 new ones) and if !consteval
calls those through extern "C" _Zmangled_name symbols.  The functions
are always_inline.

And then logic_error etc. have for C++26 (precisely for
__cpp_lib_constexpr_exceptions >= 202502L) constexpr definitions of
cdtors/methods.  This results in slightly larger code (a few insns at most)
at runtime for C++26, e.g. instead of calling say some logic error
cdtor/method with 2 arguments it calls some __cow_string one with 2
arguments but + 8 bytes pointer additions on both.

The patch also 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 and there are
actually constexpr/consteval uses of those) are constexpr for C++26
constexpr exceptions.

The patch does that by splitting the bits/functexcept.h header:
1) bits/functexcept.h stays for the __throw_* functions which are (at
least for now) never constexpr (the <ios>, <system_error>, <future>
and <functional> std::exception derived classes) or are never used
or never used in constexpr/consteval contexts (<exception>, <typeinfo>
std::exception derived classes and std::range_error).
2) bits/new_{throw,except}.h for __throw_bad_alloc/__throw_bad_array_new_length
and std::bad_alloc/std::bad_array_new_length (where <new> includes
<bits/new_except.h> and <bits/new_throw.h> as well for the C++26 constexpr
exceptions case)
3) for the most complicated <stdexcept> stuff, one header
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 one header without header guards which will
depending on __glibcxx_exc_in_string include one or the other because
<string> vs. <string_view> vs. <stdexcept> have heavy interdependencies

2025-12-11  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/bits/new_except.h: New file.
* include/bits/new_throw.h: New file.
* include/bits/stdexcept_throw.h: New file.
* include/bits/stdexcept_throwdef.h: New file.
* include/bits/stdexcept_throwfwd.h: New file.
* include/std/stdexcept: Include bits/stdexcept_except.h and move
everything after <string> include except for std::range_error into
include/bits/stdexcept_except.h.
(std::range_error): If __cpp_lib_constexpr_exceptions >= 202502L
make all cdtors and methods constexpr.
* include/bits/stdexcept_except.h: New file.
* 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>.
* include/std/shared_mutex: Include <bits/new_throw.h>.
* include/std/flat_map: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/std/syncstream: Remove <bits/functexcept.h> include.
* include/std/flat_set: Likewise.
* include/std/bitset: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/std/string_view: Don't include <bits/functexcept.h>, include
<bits/stdexcept_throw.h> early if __glibcxx_exc_in_string is not
defined and include <bits/stdexcept_throw.h> 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): Define if __glibcxx_exc_in_string wasn't
defined before including <bits/stdexcept_throw.h>.
* include/std/array: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/std/inplace_vector: Likewise.
* include/std/string: Include <bits/stdexcept_except.h> and
<bits/stdexcept_throw.h> after bits/basic_string.tcc include if
C++26 constexpr exceptions are enabled and include
<bits/stdexcept_throw.h> instead of <bits/functexcept.h> early.
(__glibcxx_exc_in_string): Define early to 1, undefine at the end.
* include/std/deque: Include <bits/stdexcept_throw.h>.
* include/bits/new_allocator.h: Include <bits/new_throw.h> instead
of <bits/functexcept.h>.
* include/bits/stl_algobase.h: Remove <bits/functexcept.h> include.
* include/bits/stl_vector.h: Include <bits/stdexcept_throw.h> instead
of <bits/functexcept.h>.
* include/bits/memory_resource.h: Include <bits/new_throw.h> instead
of <bits/functexcept.h>.
* include/bits/functexcept.h: Guard everything after includes with
#if _GLIBCXX_HOSTED.
(__throw_bad_alloc, __throw_bad_array_new_length,  __throw_logic_error,
__throw_domain_error, __throw_invalid_argument, __throw_length_error,
__throw_out_of_range, __throw_out_of_range_fmt, __throw_runtime_error,
__throw_overflow_error, __throw_underflow_error): Move declarations to
other headers - <bits/new_throw.h> and <bits/stdexcept_throwfwd.h>.
* include/bits/stl_map.h: Include <bits/stdexcept_throw.h> instead
of <bits/functexcept.h>.
* include/bits/hashtable_policy.h: Include <bits/stdexcept_throw.h>
instead of <bits/functexcept.h>.
* include/bits/formatfwd.h (std::__throw_format_error): Remove
declaration.
* include/bits/specfun.h: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/bits/basic_ios.h: Include <bits/functexcept.h>.
* include/bits/locale_classes.h: Likewise.
* include/tr1/cmath: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/tr1/memory: Remove <bits/functexcept.h> include.
* include/tr1/array: Include <bits/stdexcept_throw.h>.
* include/ext/vstring_util.h: Include <bits/stdexcept_throw.h> instead
of <bits/functexcept.h>.
* include/ext/bitmap_allocator.h: Include <bits/new_throw.h> instead
of <bits/functexcept.h>.
* include/ext/mt_allocator.h: Likewise.
* include/ext/malloc_allocator.h: Likewise.
* include/ext/debug_allocator.h: Include <bits/stdexcept_throw.h>
instead of <bits/functexcept.h>.
* include/ext/concurrence.h: Include <bits/exception_defines.h>
instead of <bits/functexcept.h>.
* include/ext/throw_allocator.h: Include <bits/new_throw.h> and
<bits/stdexcept_throw.h> instead of <bits/functexcept.h>.
* include/ext/string_conversions.h: Include <bits/stdexcept_throw.h>
instead of <bits/functexcept.h>.
* include/ext/pool_allocator.h: Include <bits/new_throw.h> instead
of <bits/functexcept.h>.
* include/ext/ropeimpl.h: Include <bits/stdexcept_throw.h> instead of
<bits/functexcept.h>.
* include/tr2/dynamic_bitset: Likewise.
* include/experimental/optional: Include <bits/exception_defines.h>
instead of <bits/functexcept.h>.
* include/Makefile.am (bits_freestanding): Add
${bits_srcdir}/{new,stdexcept}_{except,throw}.h
and ${bits_srcdir}/stdexcept_throw{fwd,def}.h.
* include/Makefile.in: Regenerate.
* src/c++17/floating_from_chars.cc: Remove <bits/functexcept.h>
include.
* src/c++11/regex.cc: Likewise.
* src/c++11/functexcept.cc: Likewise.
* src/c++11/snprintf_lite.cc: Include <bits/stdexcept_throw.h> instead
of <bits/functexcept.h>.
* src/c++11/thread.cc: Include <bits/functexcept.h>.
* testsuite/util/testsuite_hooks.h: Include <bits/stdexcept_throw.h>
instead of <bits/functexcept.h>.
* 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/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++/new: Include <bits/new_except.h>.
(std::bad_alloc, std::bad_array_new_length): Move defintion to
<bits/new_except.h>.
libgomp/
* omp.h.in: Include <bits/new_throw.h> instead of
<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.

86 files changed:
gcc/testsuite/g++.dg/tree-ssa/pr109442.C
gcc/testsuite/g++.dg/tree-ssa/pr110819.C
gcc/testsuite/g++.dg/tree-ssa/pr116868.C
gcc/testsuite/g++.dg/tree-ssa/pr58483.C
gcc/testsuite/g++.dg/tree-ssa/pr96945.C
libgomp/omp.h.in
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/basic_ios.h
libstdc++-v3/include/bits/formatfwd.h
libstdc++-v3/include/bits/functexcept.h
libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/memory_resource.h
libstdc++-v3/include/bits/new_allocator.h
libstdc++-v3/include/bits/new_except.h [new file with mode: 0644]
libstdc++-v3/include/bits/new_throw.h [new file with mode: 0644]
libstdc++-v3/include/bits/specfun.h
libstdc++-v3/include/bits/stdexcept_except.h [new file with mode: 0644]
libstdc++-v3/include/bits/stdexcept_throw.h [new file with mode: 0644]
libstdc++-v3/include/bits/stdexcept_throwdef.h [new file with mode: 0644]
libstdc++-v3/include/bits/stdexcept_throwfwd.h [new file with mode: 0644]
libstdc++-v3/include/bits/stl_algobase.h
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/version.def
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/experimental/optional
libstdc++-v3/include/ext/bitmap_allocator.h
libstdc++-v3/include/ext/concurrence.h
libstdc++-v3/include/ext/debug_allocator.h
libstdc++-v3/include/ext/malloc_allocator.h
libstdc++-v3/include/ext/mt_allocator.h
libstdc++-v3/include/ext/pool_allocator.h
libstdc++-v3/include/ext/ropeimpl.h
libstdc++-v3/include/ext/string_conversions.h
libstdc++-v3/include/ext/throw_allocator.h
libstdc++-v3/include/ext/vstring_util.h
libstdc++-v3/include/std/array
libstdc++-v3/include/std/bitset
libstdc++-v3/include/std/deque
libstdc++-v3/include/std/expected
libstdc++-v3/include/std/flat_map
libstdc++-v3/include/std/flat_set
libstdc++-v3/include/std/format
libstdc++-v3/include/std/future
libstdc++-v3/include/std/inplace_vector
libstdc++-v3/include/std/optional
libstdc++-v3/include/std/shared_mutex
libstdc++-v3/include/std/stdexcept
libstdc++-v3/include/std/string
libstdc++-v3/include/std/string_view
libstdc++-v3/include/std/syncstream
libstdc++-v3/include/std/variant
libstdc++-v3/include/tr1/array
libstdc++-v3/include/tr1/cmath
libstdc++-v3/include/tr1/memory
libstdc++-v3/include/tr2/dynamic_bitset
libstdc++-v3/libsupc++/new
libstdc++-v3/src/c++11/cow-stdexcept.cc
libstdc++-v3/src/c++11/functexcept.cc
libstdc++-v3/src/c++11/regex.cc
libstdc++-v3/src/c++11/snprintf_lite.cc
libstdc++-v3/src/c++11/thread.cc
libstdc++-v3/src/c++17/floating_from_chars.cc
libstdc++-v3/testsuite/18_support/exception/version.cc
libstdc++-v3/testsuite/19_diagnostics/headers/stdexcept/version.cc [new file with mode: 0644]
libstdc++-v3/testsuite/19_diagnostics/logic_error/constexpr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/19_diagnostics/runtime_error/constexpr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/allocator/105975.cc
libstdc++-v3/testsuite/20_util/expected/observers.cc
libstdc++-v3/testsuite/20_util/expected/version.cc
libstdc++-v3/testsuite/20_util/optional/constexpr/observers/3.cc
libstdc++-v3/testsuite/20_util/optional/version.cc
libstdc++-v3/testsuite/20_util/variant/constexpr.cc
libstdc++-v3/testsuite/20_util/variant/version.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc
libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc
libstdc++-v3/testsuite/util/io/verified_cmd_line_input.cc
libstdc++-v3/testsuite/util/testsuite_hooks.h

index ea5800aa134013c983d7a81337f135cd8d0b4127..dc335d136567373644081b495c53c2b4a899d466 100644 (file)
@@ -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 } } }
index c0e8495ca545b203e659083b2d85057bc45e9fc3..8305589a19d0b4f189b672f4282b495098dc426e 100644 (file)
@@ -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 } } }
index 1794818f1f01218bfed6f4fe430c8ee5b6b832b3..8580661d35ce9b23657e8dd79e2b7660de5f3bfa 100644 (file)
@@ -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 } } }
index c0e8495ca545b203e659083b2d85057bc45e9fc3..8305589a19d0b4f189b672f4282b495098dc426e 100644 (file)
@@ -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 } } }
index 9fb2cbc2dcce01e1d1301bb93f5b40275ff9a1cb..07c141340c0b11eac952daaf7ef62932bc43e708 100644 (file)
@@ -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 } } }
index 329d8dc35e071a34d1c8663b5ec7bcb980223559..4e1b95b3475f94b4a673651f62e2ac445bb4eb28 100644 (file)
@@ -442,7 +442,7 @@ extern const char *omp_get_uid_from_device (int) __GOMP_NOTHROW;
 #if __cplusplus >= 201103L
 
 /* std::__throw_bad_alloc and std::__throw_bad_array_new_length.  */
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
 
 namespace omp
 {
index 4713ff2208d1ec0de3b9abc503960c389c9621a5..44e487682d45f21d980dfa5dc043e8202ee7f6ec 100644 (file)
@@ -2576,6 +2576,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.
index 847fc13151f582054f60cd7c209c1ebdc120501a..80f0b8bebd89a5107d49116542265853d090a879 100644 (file)
@@ -137,6 +137,8 @@ bits_freestanding = \
        ${bits_srcdir}/intcmp.h \
        ${bits_srcdir}/invoke.h \
        ${bits_srcdir}/iterator_concepts.h \
+       ${bits_srcdir}/new_except.h \
+       ${bits_srcdir}/new_throw.h \
        ${bits_srcdir}/max_size_type.h \
        ${bits_srcdir}/memoryfwd.h \
        ${bits_srcdir}/monostate.h \
@@ -155,6 +157,10 @@ bits_freestanding = \
        ${bits_srcdir}/ranges_util.h \
        ${bits_srcdir}/refwrap.h \
        ${bits_srcdir}/sat_arith.h \
+       ${bits_srcdir}/stdexcept_except.h \
+       ${bits_srcdir}/stdexcept_throw.h \
+       ${bits_srcdir}/stdexcept_throwdef.h \
+       ${bits_srcdir}/stdexcept_throwfwd.h \
        ${bits_srcdir}/stl_algo.h \
        ${bits_srcdir}/stl_algobase.h \
        ${bits_srcdir}/stl_construct.h \
index 1d6171bac9d1e6f75cd65ece8aa168c612454fe8..d108eb0155b0778612ba541885a5dc571345700c 100644 (file)
@@ -495,6 +495,8 @@ bits_freestanding = \
        ${bits_srcdir}/intcmp.h \
        ${bits_srcdir}/invoke.h \
        ${bits_srcdir}/iterator_concepts.h \
+       ${bits_srcdir}/new_except.h \
+       ${bits_srcdir}/new_throw.h \
        ${bits_srcdir}/max_size_type.h \
        ${bits_srcdir}/memoryfwd.h \
        ${bits_srcdir}/monostate.h \
@@ -513,6 +515,10 @@ bits_freestanding = \
        ${bits_srcdir}/ranges_util.h \
        ${bits_srcdir}/refwrap.h \
        ${bits_srcdir}/sat_arith.h \
+       ${bits_srcdir}/stdexcept_except.h \
+       ${bits_srcdir}/stdexcept_throw.h \
+       ${bits_srcdir}/stdexcept_throwdef.h \
+       ${bits_srcdir}/stdexcept_throwfwd.h \
        ${bits_srcdir}/stl_algo.h \
        ${bits_srcdir}/stl_algobase.h \
        ${bits_srcdir}/stl_construct.h \
index ecb3b561932279a86368f9b4639aab33a108bc79..f616ccf45266be62e68a0eb1a932d2fd59fe3a40 100644 (file)
@@ -34,6 +34,7 @@
 #pragma GCC system_header
 #endif
 
+#include <bits/functexcept.h>
 #include <bits/localefwd.h>
 #include <bits/locale_classes.h>
 #include <bits/locale_facets.h>
index 883b772752a790019e53c473c9a3ef49ffa5d2f3..d2dfb17492d189c2df960fe517a9ec97874e76b5 100644 (file)
@@ -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
index b1bf43a586a17294605143695be4c1f54bfcd0b2..437ba48a6a72a974882ca8f913608b252d9a2963 100644 (file)
 #include <bits/c++config.h>
 #include <bits/exception_defines.h>
 
+#if _GLIBCXX_HOSTED
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-#if _GLIBCXX_HOSTED
   // Helper for exception objects in <except>
   void
   __throw_bad_exception(void) __attribute__((__noreturn__));
 
-  // Helper for exception objects in <new>
-  void
-  __throw_bad_alloc(void) __attribute__((__noreturn__));
-
-  void
-  __throw_bad_array_new_length(void) __attribute__((__noreturn__));
-
   // Helper for exception objects in <typeinfo>
   void
   __throw_bad_cast(void) __attribute__((__noreturn__,__cold__));
@@ -63,37 +55,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_bad_typeid(void) __attribute__((__noreturn__,__cold__));
 
   // Helpers for exception objects in <stdexcept>
-  void
-  __throw_logic_error(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_domain_error(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_invalid_argument(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_length_error(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_out_of_range(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__,__cold__))
-    __attribute__((__format__(__gnu_printf__, 1, 2)));
-
-  void
-  __throw_runtime_error(const char*) __attribute__((__noreturn__,__cold__));
-
   void
   __throw_range_error(const char*) __attribute__((__noreturn__,__cold__));
 
-  void
-  __throw_overflow_error(const char*) __attribute__((__noreturn__,__cold__));
-
-  void
-  __throw_underflow_error(const char*) __attribute__((__noreturn__,__cold__));
-
   // Helpers for exception objects in <ios>
   void
   __throw_ios_failure(const char*) __attribute__((__noreturn__,__cold__));
@@ -113,31 +77,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   __throw_bad_function_call() __attribute__((__noreturn__,__cold__));
 
-#else // ! HOSTED
-
-  __attribute__((__noreturn__)) inline void
-  __throw_invalid_argument(const char*)
-  { std::__terminate(); }
-
-  __attribute__((__noreturn__)) inline void
-  __throw_out_of_range(const char*)
-  { std::__terminate(); }
-
-  __attribute__((__noreturn__)) inline void
-  __throw_out_of_range_fmt(const char*, ...)
-  { std::__terminate(); }
-
-  __attribute__((__noreturn__)) inline void
-  __throw_runtime_error(const char*)
-  { std::__terminate(); }
-
-  __attribute__((__noreturn__)) inline void
-  __throw_overflow_error(const char*)
-  { std::__terminate(); }
-
-#endif // HOSTED
-
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // HOSTED
 
 #endif
index 048855d5405b399bfdcc86f9c246d09092591485..2af314a634d651cbe47abb0fe6197a91fbcfe692 100644 (file)
@@ -32,6 +32,7 @@
 #define _HASHTABLE_POLICY_H 1
 
 #include <tuple>               // for std::tuple, std::forward_as_tuple
+#include <bits/stdexcept_throw.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
index a759b7d9180782e29178daf71f66ece5c95ba51d..c49a12fdc4c285ffb4e506e79f1d6d594f959f60 100644 (file)
@@ -38,6 +38,7 @@
 #pragma GCC system_header
 #endif
 
+#include <bits/functexcept.h>
 #include <bits/localefwd.h>
 #include <string>
 #include <ext/atomicity.h>
index d4ed06c89ff53697cb79845eadcdbd86a26395e4..5be7fd37832b4916b44c6243f50f6c4676f33ff4 100644 (file)
@@ -38,7 +38,7 @@
 
 #include <new>                         // operator new(size_t, void*)
 #include <cstddef>                     // size_t, max_align_t, byte
-#include <bits/functexcept.h>          // __throw_bad_array_new_length
+#include <bits/new_throw.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
 #include <ext/numeric_traits.h>                // __int_traits
index 8f1bc57d4058f6631a23e0dafe758ead887994ef..0948876f0a949e5a7647c6dfedd5001751b1743e 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <bits/c++config.h>
 #include <new>
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
 #include <bits/move.h>
 #if __cplusplus >= 201103L
 #include <type_traits>
diff --git a/libstdc++-v3/include/bits/new_except.h b/libstdc++-v3/include/bits/new_except.h
new file mode 100644 (file)
index 0000000..41cefbf
--- /dev/null
@@ -0,0 +1,110 @@
+// Exception classes for <new> -*- 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/new_except.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{new}
+ */
+
+//
+// ISO C++ 14882: 19.1  Exception classes
+//
+
+#ifndef _NEW_EXCEPT_H
+#define _NEW_EXCEPT_H 1
+
+#include <bits/c++config.h>
+#include <bits/exception_defines.h>
+#include <bits/exception.h>
+
+extern "C++"
+{
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @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
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+}
+
+#endif
diff --git a/libstdc++-v3/include/bits/new_throw.h b/libstdc++-v3/include/bits/new_throw.h
new file mode 100644 (file)
index 0000000..94afd9e
--- /dev/null
@@ -0,0 +1,76 @@
+// Function-Based Exception Support -*- 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/new_throw.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{new}
+ */
+
+//
+// ISO C++ 14882: 19.1  Exception classes
+//
+
+#ifndef _NEW_THROW_H
+#define _NEW_THROW_H 1
+
+#include <bits/c++config.h>
+#include <bits/exception_defines.h>
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+     && __cpp_constexpr_exceptions >= 202411L)
+#include <bits/new_except.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if _GLIBCXX_HOSTED
+#if (__cpp_exceptions && __cplusplus > 202302L \
+     && __cpp_constexpr_exceptions >= 202411L)
+  // 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();
+  }
+#else
+  // Helper for exception objects in <new>
+  void
+  __throw_bad_alloc(void) __attribute__((__noreturn__));
+
+  void
+  __throw_bad_array_new_length(void) __attribute__((__noreturn__));
+#endif
+#endif // HOSTED
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif
index 39e26986c9b60e3625c04cde2112475fae0cac41..ae649e27401658487bab6fce93772588aa65c09f 100644 (file)
@@ -40,6 +40,7 @@
 # error include <cmath> and define __STDCPP_WANT_MATH_SPEC_FUNCS__
 #endif
 
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algobase.h>
 #include <limits>
 #include <type_traits>
diff --git a/libstdc++-v3/include/bits/stdexcept_except.h b/libstdc++-v3/include/bits/stdexcept_except.h
new file mode 100644 (file)
index 0000000..4a6a3b2
--- /dev/null
@@ -0,0 +1,552 @@
+// Exception classes for <stdexcept>  -*- 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_except.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{stdexcept}  */
+
+#ifndef _STDEXCEPT_EXCEPT_H
+#define _STDEXCEPT_EXCEPT_H 1
+
+#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 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 /* _STDEXCEPT_EXCEPT_H */
diff --git a/libstdc++-v3/include/bits/stdexcept_throw.h b/libstdc++-v3/include/bits/stdexcept_throw.h
new file mode 100644 (file)
index 0000000..800bdcc
--- /dev/null
@@ -0,0 +1,61 @@
+// Function-Based Exception Support -*- 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_throw.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{stdexcept}
+ */
+
+//
+// ISO C++ 14882: 19.1  Exception classes
+//
+
+#include <bits/c++config.h>
+#include <bits/exception_defines.h>
+
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+     && __cpp_constexpr_exceptions >= 202411L)
+// 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_STRING) || __glibcxx_exc_in_string == 2
+#ifdef __glibcxx_exc_in_string
+#include <bits/stdexcept_throwfwd.h>
+#else
+#include <bits/stdexcept_throwdef.h>
+#endif
+#endif
+#if !defined(_GLIBCXX_STRING) && __glibcxx_exc_in_string != 2
+#include <string>
+#endif
+#else
+#include <bits/stdexcept_throwfwd.h>
+#endif
diff --git a/libstdc++-v3/include/bits/stdexcept_throwdef.h b/libstdc++-v3/include/bits/stdexcept_throwdef.h
new file mode 100644 (file)
index 0000000..8c31918
--- /dev/null
@@ -0,0 +1,177 @@
+// Function-Based Exception Support -*- 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_throwdef.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{stdexcept}
+ */
+
+//
+// ISO C++ 14882: 19.1  Exception classes
+//
+
+#ifndef _STDEXCEPT_THROWDEF_H
+#define _STDEXCEPT_THROWDEF_H 1
+
+#include <bits/c++config.h>
+#include <bits/exception_defines.h>
+#if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \
+     && __cpp_constexpr_exceptions >= 202411L)
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // 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
+      _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_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);
+    } 
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif
+
+#endif
diff --git a/libstdc++-v3/include/bits/stdexcept_throwfwd.h b/libstdc++-v3/include/bits/stdexcept_throwfwd.h
new file mode 100644 (file)
index 0000000..57bf899
--- /dev/null
@@ -0,0 +1,125 @@
+// Function-Based Exception Support -*- 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_throwfwd.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{stdexcept}
+ */
+
+//
+// ISO C++ 14882: 19.1  Exception classes
+//
+
+#ifndef _STDEXCEPT_THROWFWD_H
+#define _STDEXCEPT_THROWFWD_H 1
+
+#include <bits/c++config.h>
+#include <bits/exception_defines.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if _GLIBCXX_HOSTED
+#if (__cpp_exceptions && __cplusplus > 202302L \
+     && __cpp_constexpr_exceptions >= 202411L)
+  // Helper for exception objects in <stdexcept>
+  [[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_overflow_error(const char*);
+  [[noreturn, __gnu__::__always_inline__, __gnu__::__cold__]] constexpr void
+  __throw_underflow_error(const char*);
+#else
+  // Helpers for exception objects in <stdexcept>
+  void
+  __throw_logic_error(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_domain_error(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_invalid_argument(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_length_error(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_out_of_range(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_out_of_range_fmt(const char*, ...)
+    __attribute__((__noreturn__,__cold__,__format__(__gnu_printf__, 1, 2)));
+
+  void
+  __throw_runtime_error(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_overflow_error(const char*) __attribute__((__noreturn__,__cold__));
+
+  void
+  __throw_underflow_error(const char*) __attribute__((__noreturn__,__cold__));
+#endif
+
+#else // ! HOSTED
+
+  __attribute__((__noreturn__)) inline void
+  __throw_invalid_argument(const char*)
+  { std::__terminate(); }
+
+  __attribute__((__noreturn__)) inline void
+  __throw_out_of_range(const char*)
+  { std::__terminate(); }
+
+  __attribute__((__noreturn__)) inline void
+  __throw_out_of_range_fmt(const char*, ...)
+  { std::__terminate(); }
+
+  __attribute__((__noreturn__)) inline void
+  __throw_runtime_error(const char*)
+  { std::__terminate(); }
+
+  __attribute__((__noreturn__)) inline void
+  __throw_overflow_error(const char*)
+  { std::__terminate(); }
+
+#endif // HOSTED
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif
index 443cbef76dee31aa273564585db82893a6063f14..61d050f57dec85028fe06e6881667018395c5e82 100644 (file)
@@ -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>
index 62d66cef6b2e27cecfc338cec672b952c60e4c36..46cbfbb002d8f1ef81962070230ad5693e5057aa 100644 (file)
@@ -56,7 +56,7 @@
 #ifndef _STL_MAP_H
 #define _STL_MAP_H 1
 
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/concept_check.h>
 #if __cplusplus >= 201103L
 #include <initializer_list>
index 7625333c9ad807d14814f0f467453268a82596fc..f914e77097baefee01358d4ad23c789285cb692d 100644 (file)
@@ -57,7 +57,7 @@
 #define _STL_VECTOR_H 1
 
 #include <bits/stl_iterator_base_funcs.h>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/concept_check.h>
 #if __cplusplus >= 201103L
 #include <initializer_list>
index ed47cc8bef802dfc4e084644f79ab478cbdc9458..5b95db19ac66cba8d956887a1c3e9676a5bbfd14 100644 (file)
@@ -2220,10 +2220,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";
   };
index a3125b65b3588cc2d8384c8bcd68decb5b8bc91f..eee9890a72b030237d6b4274de7c93ab779affb4 100644 (file)
 
 #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) */
index 0cee44204d168628cb1301865be3b8dcc01924cf..5ae576e132e0e3aed9582d82e77ef3d1312ae5a2 100644 (file)
@@ -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>
index 35c1649f67c3a6bb2fe168ab9ac595ba537473d6..6e73e193c9d65fc22f789e251722095c979d5bf6 100644 (file)
@@ -32,7 +32,7 @@
 #include <bits/requires_hosted.h> // GNU extensions are currently omitted
 
 #include <utility> // For std::pair.
-#include <bits/functexcept.h> // For __throw_bad_alloc().
+#include <bits/new_throw.h> // For __throw_bad_alloc().
 #include <bits/stl_function.h> // For greater_equal, and less_equal.
 #include <new> // For operator new.
 #include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT
index 2c3a893a2f15beed38f1cc3431f8af51784fe8dd..2afbc175cc6b6a1abff8db08b87d726f476afe97 100644 (file)
@@ -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>
 
index f0c730a2c6dfc696cdac6193b3ae545a641177f8..d0d85c4304eccbca5289fa66d7d209408450bf78 100644 (file)
@@ -45,7 +45,7 @@
 #include <bits/requires_hosted.h> // GNU extensions are currently omitted
 
 #include <stdexcept>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <ext/alloc_traits.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
index 9fef725fff8e57b99367161df3359b58704e1526..8f36ac2976eb66925e54dafd402b6aaa62aeb7b4 100644 (file)
@@ -34,7 +34,7 @@
 #include <cstdlib>
 #include <cstddef>
 #include <new>
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
 #include <bits/move.h>
 #if __cplusplus >= 201103L
 #include <type_traits>
index 6a75349f898a90d5d33d58f206550fb4b981256e..7b86c1ba5b87d84874222e8e55e9740626cd6691 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <new>
 #include <cstdlib>
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
 #include <ext/atomicity.h>
 #include <bits/move.h>
 #if __cplusplus >= 201103L
index c40c785d4bfedccc7f81f76167d2ca05c7606baa..ab9319775bd5160e15e48be1483a059a63cd7dab 100644 (file)
@@ -47,7 +47,7 @@
 #include <bits/c++config.h>
 #include <cstdlib>
 #include <new>
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
 #include <ext/atomicity.h>
 #include <ext/concurrence.h>
 #include <bits/move.h>
index 00b334cb4f4e9423b59af3dfb458405a76b52ae2..f3d199b5a2da79661b09c6b0377eef45f37db1b1 100644 (file)
@@ -42,7 +42,7 @@
 
 #include <cstdio>
 #include <ostream>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 
 #include <ext/algorithm> // For copy_n and lexicographical_compare_3way
 #include <ext/memory> // For uninitialized_copy_n
index a9e478b4276013937ae1a6611f28d0dd2c1930e9..f44f0dee72848aee553c1e8ce452211a84e495ac 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <bits/c++config.h>
 #include <ext/numeric_traits.h>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <cstdlib>
 #include <cwchar>
 #include <cstdio>
index e4c1753f88040562f51f8e7b3ae721cccd42acfe..5d5fc3f2aed134c3ab16fa8f072cdaf07250149b 100644 (file)
@@ -55,7 +55,8 @@
 #include <ostream>
 #include <stdexcept>
 #include <utility>
-#include <bits/functexcept.h>
+#include <bits/new_throw.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/move.h>
 #if __cplusplus >= 201103L
 # include <functional>
index c6c7c8f4bba80d4ba1cf6717e46a7c3eb728f306..a68d1f086ce3339727115c38812071ca081f5d51 100644 (file)
@@ -39,7 +39,7 @@
 #include <ext/vstring_fwd.h>
 #include <debug/debug.h>
 #include <bits/stl_function.h>  // For less
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/localefwd.h>
 #include <bits/ostream_insert.h>
 #include <bits/stl_iterator.h>
index 12f010921db14073dc6a414de43ad94e28e968d2..5cc5a9b13e4f4cb6fb318b76551f00f69337905c 100644 (file)
@@ -41,7 +41,7 @@
 #include <initializer_list>
 
 #include <type_traits>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algobase.h>
 #include <bits/range_access.h> // std::begin, std::end etc.
 #include <bits/utility.h>      // std::index_sequence, std::tuple_size
index ece359369094585b4e38990af1ae6b5c13e8aff4..0cf97c907a79caf23f0742b86b493f7161088ccd 100644 (file)
@@ -46,8 +46,8 @@
 #pragma GCC system_header
 #endif
 
-#include <bits/functexcept.h>   // For invalid_argument, out_of_range,
-                                // overflow_error
+#include <bits/stdexcept_throw.h> // For invalid_argument, out_of_range,
+                                 // overflow_error
 #include <bits/stl_algobase.h>  // For std::fill
 
 #if _GLIBCXX_HOSTED
index 600f607ac7d32e66cdd570a168e5b6f3bafa012b..5cd953217f45e9f267522b3eff9aa30ea9ff6272 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <bits/requires_hosted.h> // containers are hosted only
 
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algobase.h>
 #include <bits/allocator.h>
 #include <bits/stl_construct.h>
index a03a7d3f722f460252f485d2c938128fc8d1d449..948c2cbe6085e1d02757de51b09efde0d19328a2 100644 (file)
@@ -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); }
 
index e48c3eae07fdb0b131a8ed4b0b79815218b695e6..637c3b7fe0d07d7cd478e64687c86e0391f9c29e 100644 (file)
@@ -47,7 +47,7 @@
 #include <ranges> // views::zip
 #include <type_traits>
 #include <vector>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algo.h>
 #include <bits/stl_function.h>  // less
 #include <bits/stl_pair.h>
index 3a1f5ba10dad9e231982a72eb373a5b80a8b8a28..286290896ae058b6cbfb8905fcd3caf0764906c2 100644 (file)
@@ -47,7 +47,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>
index f64f35a202e0536db3a558547774471f272f0cb8..2e4463c65969b0a8c89da7fb0ce9b0fd704a6ed1 100644 (file)
@@ -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
@@ -219,12 +220,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
@@ -233,6 +242,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?
index 080690064a9108ca0d2c307b29c5509b7c939f5c..a4dc925dac4fb39c480ea045cb7d571d7cf29882 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 
 #include <bits/requires_hosted.h> // concurrency
+#include <bits/functexcept.h>
 
 #if __cplusplus < 201103L
 # include <bits/c++0x_warning.h>
index 0f7716cb64de8dfd48e8d7e9aa8e17742a6c9d32..df95c1e5c02159765d892b235d4c063633dc09e4 100644 (file)
@@ -38,6 +38,7 @@
 #ifdef __glibcxx_inplace_vector // C++ >= 26
 #include <compare>
 #include <initializer_list>
+#include <bits/stdexcept_throw.h>
 #include <bits/range_access.h>
 #include <bits/ranges_base.h> // borrowed_iterator_t, __detail::__container_compatible_range
 #include <bits/ranges_util.h> // subrange
index 8b9fa9244213e735cd27166803f4789e3db25c18..1703dc9c228a12a96fb5f2b5c20062a4c87dc63d 100644 (file)
@@ -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()); }
 
index 92f6227dafb70fa390c021b3b3bb1502d7c43c5f..1e2e7b63b62b85cab998ec21bf4c76b98f5d4df8 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <bits/chrono.h>
 #include <bits/error_constants.h>
+#include <bits/new_throw.h>
 #include <bits/functexcept.h>
 #include <bits/move.h>        // move, __exchange
 #include <bits/std_mutex.h>   // defer_lock_t
index ea19569df63433de46f7023464c7bc91c03f93fd..522653edb693f132f269a2b0f160824c93d8752c 100644 (file)
 
 #include <exception>
 #include <string>
+#include <bits/stdexcept_except.h>
 
 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:
+#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;
@@ -269,36 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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
index 918b4158b47531ca46e6925edb0c507b1a82b539..671bad199f58a704d577e97841c7359ebc614608 100644 (file)
@@ -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>
 #include <bits/stl_iterator.h>
 #include <bits/stl_function.h> // For less
 #include <ext/numeric_traits.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algobase.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_except.h>
+#undef __glibcxx_exc_in_string
+#include <bits/stdexcept_throw.h>
+#else
+#undef __glibcxx_exc_in_string
+#endif
 
 #define __glibcxx_want_algorithm_default_value_type
 #define __glibcxx_want_allocator_traits_is_always_equal
index b226544fa6f2bff5d4c2575dad2150cc92127975..da9085b039d789e6ece4be53d22a37366429751d 100644 (file)
 #if __cplusplus >= 201703L
 
 #include <bits/char_traits.h>
-#include <bits/functexcept.h>
+#ifndef __glibcxx_exc_in_string
+#define __glibcxx_exc_in_string 2
+#include <bits/stdexcept_throw.h>
+#endif
 #include <bits/functional_hash.h>
 #include <bits/range_access.h>
 #include <bits/stl_algobase.h>
@@ -918,6 +921,14 @@ _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)
+#include <bits/stdexcept_throw.h>
+#endif
+#endif
+
 #endif // __cplusplus <= 201402L
 
-#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
+#endif // _GLIBCXX_STRING_VIEW
index 1e1759714c690dfb0fff41eb0156a5e4d55361fa..22a8298ef0118bda6265241fd31507e2dd01de5a 100644 (file)
@@ -45,7 +45,6 @@
 
 #include <bits/alloc_traits.h>
 #include <bits/allocator.h>
-#include <bits/functexcept.h>
 #include <bits/std_mutex.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
index f2f55837461b91a2f3e2cd5115d4ef01a3938a27..51d21daf46c318608a56e3dc05712f651cc7f060 100644 (file)
@@ -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
@@ -1410,24 +1411,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",
@@ -1437,6 +1447,7 @@ namespace __detail::__variant
       };
       _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
     }
+#undef _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
   };
 
   template<typename... _Types>
index 118442bd98dc7c901ae905bb4fe00074af7e8f24..1622c77b3853232c1482cec3f523f60ef936a567 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 
 #include <bits/requires_hosted.h> // TR1
+#include <bits/stdexcept_throw.h>
 
 #include <bits/stl_algobase.h>
 
index e97e03ca3ed51ab3cf8ed481a939b611cd1fc392..8339ea14c4b903c13544097bd320bfe39836032c 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 
 #include <bits/requires_hosted.h> // TR1
+#include <bits/stdexcept_throw.h>
 
 #include <cmath>
 
index 760d7d1212a617781cad455dc8e67f37a87b2081..9b0d1866a0d4530eb453458d717a25b117968499 100644 (file)
@@ -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>
index b308e7283c2bcf6bcd5bdbf9eefdf31381a7ee82..a07818125ecba48db2de8954ac5b00e2aad3abb3 100644 (file)
@@ -37,7 +37,7 @@
 #include <vector>
 #include <string>
 #include <istream>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <bits/stl_algo.h>     // For fill
 #include <bits/cxxabi_forced.h>
 
index 018adc0c4ede90dd059830ecc96d5f0daa8bb76e..1db8e84d5e1b35cbd99ea04200e1631c2e02eeae 100644 (file)
@@ -47,6 +47,7 @@
 #define __glibcxx_want_destroying_delete
 #define __glibcxx_want_constexpr_new
 #include <bits/version.h>
+#include <bits/new_except.h> // std::bad_alloc, std::bad_array_new_length
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wc++11-extensions" // scoped enum
@@ -57,63 +58,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
index 0afa3580fd315efda9ad414816a16acb9e9f2638..163ab5fc5978de6f3b4afe452f86ca84d2de5f51 100644 (file)
@@ -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),
index 6f876584e7cae307c88c5b0df56ab555a4dabf96..aafa9ef9c35183455dbdabf5bc42df49d98697a7 100644 (file)
@@ -20,7 +20,6 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-#include <bits/functexcept.h>
 #include <cstdlib>
 #include <exception>
 #include <stdexcept>
index ae181d6e74236adb71768ccfcb9d60844d732c67..007abf52d80b0e06fbe31d9d4dd991691d7f26cf 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <stdexcept>
 #include <bits/regex_error.h>
-#include <bits/functexcept.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
index 8b72fdb4844eee5e66d48e13663f6b29ad8e99f4..955691c3ceb7a292ac8455ce2e4672380052cb96 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <stdarg.h>
 #include <stddef.h>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 
 namespace __gnu_cxx {
 
index 5cfe56453af6aa253639e307fff87d9de8440998..64ffd8fc0b41daebf6962a4e03256291807c7c57 100644 (file)
@@ -30,6 +30,7 @@
 #include <system_error>
 #include <cerrno>
 #include <cxxabi_forced.h>
+#include <bits/functexcept.h>
 
 #ifndef _GLIBCXX_USE_NANOSLEEP
 # ifdef _GLIBCXX_HAVE_SLEEP
index 9bad12c7f69ecd5ce1275e05484d3e96dd492867..d759df7d61e95aa300f7bb7c1bf340098bac8c5b 100644 (file)
@@ -45,7 +45,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <locale.h>
-#include <bits/functexcept.h>
 #if _GLIBCXX_HAVE_XLOCALE_H
 # include <xlocale.h>
 #endif
index 5707abd732f500b491ff59e23ac68b376db1dc36..a1cf532cd3f68369b23dc463de56bc547a187a11 100644 (file)
@@ -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
-
diff --git a/libstdc++-v3/testsuite/19_diagnostics/headers/stdexcept/version.cc b/libstdc++-v3/testsuite/19_diagnostics/headers/stdexcept/version.cc
new file mode 100644 (file)
index 0000000..ab2b9a5
--- /dev/null
@@ -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
diff --git a/libstdc++-v3/testsuite/19_diagnostics/logic_error/constexpr.cc b/libstdc++-v3/testsuite/19_diagnostics/logic_error/constexpr.cc
new file mode 100644 (file)
index 0000000..ae37b82
--- /dev/null
@@ -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>();
+}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/runtime_error/constexpr.cc b/libstdc++-v3/testsuite/19_diagnostics/runtime_error/constexpr.cc
new file mode 100644 (file)
index 0000000..a7d96eb
--- /dev/null
@@ -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>();
+}
index 86e855423428199bae7dba1945dce4cdee093383..ccbcfe3cb35cf743482464487f318593f771ff7a 100644 (file)
@@ -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 }
index 35cc3d8f5a3f8245b3d79ea77a3316d1b7cf4882..31aaca352ae849a87330671a50030cf64f91241d 100644 (file)
@@ -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();
index 682835ca355f0794c7cd460072b1ba00aaa069db..aacd61b7f0a9b3eaca68c9325f5924c6a33a897a 100644 (file)
 # 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
 #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
index afdac8da63e91aa5c8b6f88a1e903f38ccb5e9f5..6c9f494c1f7d3ee04220ccd6a622e1cbccfb9bfa 100644 (file)
 // <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 } };
index ae9339a01af8958116b0215a1793174efdf22894..f59cb9966fb780cf1a79b000435cee633dff28fd 100644 (file)
 # 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
 # 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
index 886fd2dab5cdfce480efb1ae4de2cc6da7fda63b..95ca60b521f8a7145e86ca7bebf4950981e6fa04 100644 (file)
@@ -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()
 {
index f7985322cc5c08db09e6a4343b85ce0511fa7004..8c4f08a2e59ab22c6660472cd198e922873c5d97 100644 (file)
 #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
 # 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
index 2797e205971dd3055a0918fed5d9e041b4b6e6e9..ef3e28cb61625cb45c4defa52ba904f47326e770 100644 (file)
@@ -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
   {
index bc06aa094251f64039488ee70649dd9e0e1cec59..5b3f4b7c1592bc7880ac0210992ac44689c88426 100644 (file)
@@ -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
   {
index 45685c2beccff34ddc22a41e8a3f45d71d1ccefb..2982af277858d2063849b6e40b0394a449ce70c5 100644 (file)
@@ -166,10 +166,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);
@@ -188,8 +187,10 @@ test_n()
     {
     }
 
+#ifndef __cpp_lib_constexpr_exceptions
   }
 #endif
+#endif
 
 #ifdef __cpp_lib_constexpr_inplace_vector
 #error remove the consteval check
@@ -243,10 +244,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);
@@ -264,8 +264,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
@@ -319,10 +321,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};
@@ -340,8 +341,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
index 4a2f193e4a58c9f45e999d6097f4b79ce5d4e6a8..b79434dd1119869dd9730d9da88085a80b6e013b 100644 (file)
@@ -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
   {
index 65b505e7f371ccc493381b46c5c5d9da45d9bf66..c1d867ee1d41b479373b7d1f8ec57a9d9cd00449 100644 (file)
@@ -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);
 
index 6a5b62f0aff38ec46698503c2af542bfb039a371..454163892add925c1664115dfb86871988a6bc06 100644 (file)
@@ -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
   {
index d5e893cc7f3822df53ecd7c1173a6da553871f07..92bd765982e245716f7ed61bed2560c62b16513c 100644 (file)
@@ -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
   {
index 580b8ae8041a5f53120eb8d227ba2c4822f6f473..f7d984e9ffa4122e569235a8c34834afe8636438 100644 (file)
@@ -38,7 +38,7 @@
 #include <limits.h>
 #include <utility>
 #include <stdlib.h>
-#include <bits/functexcept.h>
+#include <bits/exception_defines.h>
 
 namespace __gnu_pbds
 {
index bf34fd121c1b23e0557d1aee706056ac78947302..9744506103110ac850f44b9527158afa0c7a4b5a 100644 (file)
@@ -44,7 +44,7 @@
 #define _GLIBCXX_TESTSUITE_HOOKS_H
 
 #include <bits/c++config.h>
-#include <bits/functexcept.h>
+#include <bits/stdexcept_throw.h>
 #include <ctime>
 #include <stdio.h>