The if-consteval branches in std::make_exception_ptr and std::exception_ptr_cast use a try-catch block, which gives an error for -fno-exceptions. Just make them return a null pointer at compile-time when -fno-exceptions is used, because there's no way to get an active exception with -fno-exceptions.
For std::exception_ptr_cast the consteval branch doesn't depend on RTTI being enabled, so we can move the check for __cpp_rtti into the runtime branch. We can also remove the #else group and just fall through to the return nullptr statement if there was no return from whichever branch of the if-consteval was taken. Also adjust some formatting and whitespace. libstdc++-v3/ChangeLog: * libsupc++/exception_ptr.h (make_exception_ptr): Return null for consteval when -fno-exceptions is used. (exception_ptr_cast): Likewise. Allow consteval path to work with -fno-rtti. --- The 17_intro and 18_support tests all pass, and the compiler's g++.dg/cpp26/constexpr-eh* tests. The full testsuite is running now for x86_64-linux. libstdc++-v3/libsupc++/exception_ptr.h | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index ee009155a39c..709d5d1740ca 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -83,9 +83,9 @@ namespace std _GLIBCXX_VISIBILITY(default) #if __cpp_lib_exception_ptr_cast >= 202506L template<typename _Ex> - constexpr const _Ex* exception_ptr_cast(const exception_ptr&) noexcept; + constexpr const _Ex* exception_ptr_cast(const exception_ptr&) noexcept; template<typename _Ex> - void exception_ptr_cast(const exception_ptr&&) = delete; + void exception_ptr_cast(const exception_ptr&&) = delete; #endif namespace __exception_ptr @@ -138,8 +138,8 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_USE_NOEXCEPT; #if __cpp_lib_exception_ptr_cast >= 202506L template<typename _Ex> - friend constexpr const _Ex* std::exception_ptr_cast(const exception_ptr&) - noexcept; + friend constexpr const _Ex* + std::exception_ptr_cast(const exception_ptr&) noexcept; #endif const void* _M_exception_ptr_cast(const type_info&) const @@ -301,8 +301,9 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX26_CONSTEXPR exception_ptr make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT { -#if __cplusplus >= 202400L +#if __cpp_lib_exception_ptr_cast >= 202506L if consteval { +#ifdef __cpp_exceptions try { throw __ex; @@ -311,6 +312,9 @@ namespace std _GLIBCXX_VISIBILITY(default) { return current_exception(); } +#else + return exception_ptr(); +#endif } #endif #if __cplusplus >= 201103L && __cpp_rtti @@ -353,7 +357,8 @@ namespace std _GLIBCXX_VISIBILITY(default) #if __cpp_lib_exception_ptr_cast >= 202506L template<typename _Ex> [[__gnu__::__always_inline__]] - constexpr const _Ex* exception_ptr_cast(const exception_ptr& __p) noexcept + constexpr const _Ex* + exception_ptr_cast(const exception_ptr& __p) noexcept { static_assert(!std::is_const_v<_Ex>); static_assert(!std::is_reference_v<_Ex>); @@ -361,8 +366,9 @@ namespace std _GLIBCXX_VISIBILITY(default) static_assert(!std::is_array_v<_Ex>); static_assert(!std::is_pointer_v<_Ex>); static_assert(!std::is_member_pointer_v<_Ex>); -#ifdef __cpp_rtti + if consteval { +#ifdef __cpp_exceptions if (__p._M_exception_object) try { @@ -375,14 +381,14 @@ namespace std _GLIBCXX_VISIBILITY(default) catch (...) { } - return nullptr; +#endif } else { +#ifdef __cpp_rtti const type_info &__id = typeid(const _Ex&); return static_cast<const _Ex*>(__p._M_exception_ptr_cast(__id)); - } -#else - return nullptr; #endif + } + return nullptr; } #endif -- 2.50.0