On Thu, 26 Jun 2025 at 11:35, Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Wed, Jun 25, 2025 at 08:20:55PM +0100, Jonathan Wakely wrote:
> > This won't work for -fno-rtti
>
> I've missed the || __cpp_exceptions part in there, thought it is &&.
>
> Here is an updated patch which uses just one definition of
> std::exception_ptr_cast and additionally exports it from std.cc.in as well.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK, thanks


>
> 2025-06-26  Jakub Jelinek  <ja...@redhat.com>
>
>         * include/bits/version.def (exception_ptr_cast): Add.
>         * include/bits/version.h: Regenerate.
>         * libsupc++/exception: Define __glibcxx_want_exception_ptr_cast before
>         including bits/version.h.
>         * libsupc++/exception_ptr.h (std::exception_ptr_cast): Define.
>         (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Declare.
>         * libsupc++/eh_ptr.cc
>         (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Define.
>         * src/c++23/std.cc.in (std::exception_ptr_cast): Export.
>         * config/abi/pre/gnu.ver: Export
>         
> _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info
>         at CXXABI_1.3.17.
>         * testsuite/util/testsuite_abi.cc (check_version): Allow 
> CXXABI_1.3.17.
>         * testsuite/18_support/exception_ptr/exception_ptr_cast.cc: New test.
>
> --- libstdc++-v3/include/bits/version.def.jj    2025-06-24 18:53:13.751807828 
> +0200
> +++ libstdc++-v3/include/bits/version.def       2025-06-25 12:52:41.844921595 
> +0200
> @@ -2012,6 +2012,14 @@ ftms = {
>    };
>  };
>
> +ftms = {
> +  name = exception_ptr_cast;
> +  values = {
> +    v = 202506;
> +    cxxmin = 26;
> +  };
> +};
> +
>  // Standard test specifications.
>  stds[97] = ">= 199711L";
>  stds[03] = ">= 199711L";
> --- libstdc++-v3/include/bits/version.h.jj      2025-06-24 18:53:13.751807828 
> +0200
> +++ libstdc++-v3/include/bits/version.h 2025-06-25 12:52:47.754691329 +0200
> @@ -2253,4 +2253,14 @@
>  #endif /* !defined(__cpp_lib_sstream_from_string_view) && 
> defined(__glibcxx_want_sstream_from_string_view) */
>  #undef __glibcxx_want_sstream_from_string_view
>
> +#if !defined(__cpp_lib_exception_ptr_cast)
> +# if (__cplusplus >  202302L)
> +#  define __glibcxx_exception_ptr_cast 202506L
> +#  if defined(__glibcxx_want_all) || 
> defined(__glibcxx_want_exception_ptr_cast)
> +#   define __cpp_lib_exception_ptr_cast 202506L
> +#  endif
> +# endif
> +#endif /* !defined(__cpp_lib_exception_ptr_cast) && 
> defined(__glibcxx_want_exception_ptr_cast) */
> +#undef __glibcxx_want_exception_ptr_cast
> +
>  #undef __glibcxx_want_all
> --- libstdc++-v3/libsupc++/exception.jj 2025-06-12 09:49:19.924910752 +0200
> +++ libstdc++-v3/libsupc++/exception    2025-06-25 12:53:09.924564775 +0200
> @@ -38,6 +38,7 @@
>  #include <bits/exception.h>
>
>  #define __glibcxx_want_uncaught_exceptions
> +#define __glibcxx_want_exception_ptr_cast
>  #include <bits/version.h>
>
>  extern "C++" {
> --- libstdc++-v3/libsupc++/exception_ptr.h.jj   2025-06-02 11:00:06.267523918 
> +0200
> +++ libstdc++-v3/libsupc++/exception_ptr.h      2025-06-26 07:53:12.966100732 
> +0200
> @@ -80,6 +80,13 @@ namespace std _GLIBCXX_VISIBILITY(defaul
>    /// Throw the object pointed to by the exception_ptr.
>    void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
>
> +#if __cpp_lib_exception_ptr_cast >= 202506L
> +  template<typename _Ex>
> +  const _Ex* exception_ptr_cast(const exception_ptr&) noexcept;
> +  template<typename _Ex>
> +  void exception_ptr_cast(const exception_ptr&&) = delete;
> +#endif
> +
>    namespace __exception_ptr
>    {
>      using std::rethrow_exception; // So that ADL finds it.
> @@ -109,6 +116,13 @@ namespace std _GLIBCXX_VISIBILITY(defaul
>        friend void std::rethrow_exception(exception_ptr);
>        template<typename _Ex>
>        friend exception_ptr std::make_exception_ptr(_Ex) 
> _GLIBCXX_USE_NOEXCEPT;
> +#if __cpp_lib_exception_ptr_cast >= 202506L
> +      template<typename _Ex>
> +      friend const _Ex* std::exception_ptr_cast(const exception_ptr&) 
> noexcept;
> +#endif
> +
> +      const void* _M_exception_ptr_cast(const type_info&) const
> +       _GLIBCXX_USE_NOEXCEPT;
>
>      public:
>        exception_ptr() _GLIBCXX_USE_NOEXCEPT;
> @@ -283,6 +299,20 @@ namespace std _GLIBCXX_VISIBILITY(defaul
>      { return exception_ptr(); }
>  #endif
>
> +#if __cpp_lib_exception_ptr_cast >= 202506L
> +  template<typename _Ex>
> +    [[__gnu__::__always_inline__]]
> +    inline const _Ex* exception_ptr_cast(const exception_ptr& __p) noexcept
> +    {
> +#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
> +    }
> +#endif
> +
>  #undef _GLIBCXX_EH_PTR_USED
>
>    /// @} group exceptions
> --- libstdc++-v3/libsupc++/eh_ptr.cc.jj 2025-04-08 14:10:30.518900025 +0200
> +++ libstdc++-v3/libsupc++/eh_ptr.cc    2025-06-25 15:29:17.416393720 +0200
> @@ -220,4 +220,20 @@ std::rethrow_exception(std::exception_pt
>    std::terminate();
>  }
>
> +const void*
> +std::__exception_ptr::exception_ptr::_M_exception_ptr_cast(const type_info& 
> t)
> +  const noexcept
> +{
> +  void *ptr = _M_exception_object;
> +  if (__builtin_expect(ptr == nullptr, false))
> +    return nullptr;
> +  __cxa_refcounted_exception *eh
> +    = __get_refcounted_exception_header_from_obj (_M_exception_object);
> +  const type_info* __thr_type = eh->exc.exceptionType;
> +  if (t.__do_catch(__thr_type, &ptr, 1))
> +    return ptr;
> +  return nullptr;
> +}
> +
> +
>  #undef _GLIBCXX_EH_PTR_COMPAT
> --- libstdc++-v3/src/c++23/std.cc.in.jj 2025-06-12 15:50:51.400821105 +0200
> +++ libstdc++-v3/src/c++23/std.cc.in    2025-06-26 07:58:26.725045106 +0200
> @@ -1050,6 +1050,9 @@ export namespace std
>    using std::throw_with_nested;
>    using std::uncaught_exception;
>    using std::uncaught_exceptions;
> +#if __cpp_lib_exception_ptr_cast >= 202506L
> +  using std::exception_ptr_cast;
> +#endif
>  }
>
>  // 34.4 <execution>
> --- libstdc++-v3/config/abi/pre/gnu.ver.jj      2025-06-02 11:00:17.686375875 
> +0200
> +++ libstdc++-v3/config/abi/pre/gnu.ver 2025-06-25 15:32:59.627528296 +0200
> @@ -2899,6 +2899,16 @@ CXXABI_1.3.16 {
>  } CXXABI_1.3.15;
>  #endif
>
> +CXXABI_1.3.17 {
> +    # std::exception_ptr::_M_exception_ptr_cast
> +    
> _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info;
> +}
> +#ifdef __riscv
> +CXXABI_1.3.16;
> +#else
> +CXXABI_1.3.15;
> +#endif
> +
>  # Symbols in the support library (libsupc++) supporting transactional memory.
>  CXXABI_TM_1 {
>
> --- libstdc++-v3/testsuite/util/testsuite_abi.cc.jj     2025-06-02 
> 11:00:18.007371713 +0200
> +++ libstdc++-v3/testsuite/util/testsuite_abi.cc        2025-06-25 
> 15:51:56.745085075 +0200
> @@ -241,6 +241,7 @@ check_version(symbol& test, bool added)
>  #ifdef __riscv
>        known_versions.push_back("CXXABI_1.3.16");
>  #endif
> +      known_versions.push_back("CXXABI_1.3.17");
>        known_versions.push_back("CXXABI_IEEE128_1.3.13");
>        known_versions.push_back("CXXABI_TM_1");
>        known_versions.push_back("CXXABI_FLOAT128");
> --- libstdc++-v3/testsuite/18_support/exception_ptr/exception_ptr_cast.cc.jj  
>   2025-06-25 15:45:25.864969085 +0200
> +++ libstdc++-v3/testsuite/18_support/exception_ptr/exception_ptr_cast.cc     
>   2025-06-25 15:47:11.156653475 +0200
> @@ -0,0 +1,81 @@
> +// { dg-do run { target c++26 } }
> +
> +// Copyright (C) 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.
> +
> +// You should have received a copy of the GNU General Public License along
> +// with this library; see the file COPYING3.  If not see
> +// <http://www.gnu.org/licenses/>.
> +
> +// exception_ptr_cast.
> +
> +#include <exception>
> +#include <testsuite_hooks.h>
> +
> +#if __cpp_lib_exception_ptr_cast != 202506L
> +# error "__cpp_lib_exception_ptr_cast != 202506"
> +#endif
> +
> +struct A { int a; };
> +struct B : A {};
> +struct C : B {};
> +struct D {};
> +struct E : virtual C { int e; virtual ~E () {} };
> +struct F : virtual E, virtual C { int f; };
> +struct G : virtual F, virtual C, virtual E {
> +  G () : g (4) { a = 1; e = 2; f = 3; } int g;
> +};
> +
> +void test01()
> +{
> +  auto a = std::make_exception_ptr(C{ 42 });
> +  auto b = std::exception_ptr_cast<C>(a);
> +  VERIFY( b != nullptr );
> +  VERIFY( b->a == 42 );
> +  auto c = std::exception_ptr_cast<B>(a);
> +  VERIFY( c == static_cast<const B*>(b) );
> +  auto d = std::exception_ptr_cast<A>(a);
> +  VERIFY( d == static_cast<const A*>(b) );
> +  auto e = std::exception_ptr_cast<D>(a);
> +  VERIFY( e == nullptr );
> +  auto f = std::make_exception_ptr(42L);
> +  auto g = std::exception_ptr_cast<long>(f);
> +  VERIFY( g != nullptr );
> +  VERIFY( *g == 42L );
> +  try
> +    {
> +      throw G ();
> +    }
> +  catch (...)
> +    {
> +      auto h = std::current_exception();
> +      auto i = std::exception_ptr_cast<G>(h);
> +      VERIFY( i != nullptr );
> +      VERIFY( i->a == 1 && i->e == 2 && i->f == 3 && i->g == 4 );
> +      auto j = std::exception_ptr_cast<A>(h);
> +      VERIFY( j == static_cast<const A*>(i) );
> +      auto k = std::exception_ptr_cast<C>(h);
> +      VERIFY( k == static_cast<const C*>(i) );
> +      auto l = std::exception_ptr_cast<E>(h);
> +      VERIFY( l == static_cast<const E*>(i) );
> +      auto m = std::exception_ptr_cast<F>(h);
> +      VERIFY( m == static_cast<const F*>(i) );
> +      auto n = std::exception_ptr_cast<G>(a);
> +      VERIFY( n == nullptr );
> +    }
> +}
> +
> +int main()
> +{
> +  test01();
> +}
>
>
>         Jakub
>

Reply via email to