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