[PATCH] Implement std::exception_ptr under libsupc++.

Howard Hinnant howard.hinnant at gmail.com
Sun Oct 6 13:44:52 PDT 2013


On Oct 3, 2013, at 6:10 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:

> libsupc++ does not implement the dependent EH ABI and the
> functionality it uses to implement std::exception_ptr (which it
> declares as an alias of std::__exception_ptr::exception_ptr) is not
> directly exported to clients. So we have little choice but to hijack
> std::__exception_ptr::exception_ptr's (which fortunately has the
> same layout as our std::exception_ptr) copy constructor, assignment
> operator and destructor (which are part of its stable ABI), and its
> rethrow_exception(std::__exception_ptr::exception_ptr) function.
> 
> Also, remove some out of date comments.
> 
> http://llvm-reviews.chandlerc.com/D1826
> 
> Files:
>  src/exception.cpp
> 
> Index: src/exception.cpp
> ===================================================================
> --- src/exception.cpp
> +++ src/exception.cpp
> @@ -10,6 +10,7 @@
> #include <stdio.h>
> 
> #include "exception"
> +#include "new"
> 
> #ifndef __has_include
> #define __has_include(inc) 0
> @@ -143,28 +144,61 @@
> 
> #endif
> 
> +#if defined(__GLIBCXX__)
> +
> +// libsupc++ does not implement the dependent EH ABI and the functionality
> +// it uses to implement std::exception_ptr (which it declares as an alias of
> +// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
> +// we have little choice but to hijack std::__exception_ptr::exception_ptr's
> +// (which fortunately has the same layout as our std::exception_ptr) copy
> +// constructor, assignment operator and destructor (which are part of its
> +// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
> +// function.
> +
> +namespace __exception_ptr
> +{
> +
> +struct exception_ptr
> +{
> +    void* __ptr_;
> +
> +    exception_ptr(const exception_ptr&) _NOEXCEPT;
> +    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
> +    ~exception_ptr() _NOEXCEPT;
> +};
> +
> +}
> +
> +_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
> +
> +#endif
> 
> exception_ptr::~exception_ptr() _NOEXCEPT
> {
> #if HAVE_DEPENDENT_EH_ABI
>     __cxa_decrement_exception_refcount(__ptr_);
> +#elif defined(__GLIBCXX__)
> +    reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
> #else
>     #warning exception_ptr not yet implemented
>     printf("exception_ptr not yet implemented\n");
>     ::abort();
> -#endif  // __APPLE__
> +#endif
> }
> 
> exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
>     : __ptr_(other.__ptr_)
> {
> #if HAVE_DEPENDENT_EH_ABI
>     __cxa_increment_exception_refcount(__ptr_);
> +#elif defined(__GLIBCXX__)
> +    new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
> +        reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
> #else
>     #warning exception_ptr not yet implemented
>     printf("exception_ptr not yet implemented\n");
>     ::abort();
> -#endif  // __APPLE__
> +#endif
> }
> 
> exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
> @@ -177,11 +211,15 @@
>         __ptr_ = other.__ptr_;
>     }
>     return *this;
> -#else  // __APPLE__
> +#elif defined(__GLIBCXX__)
> +    *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
> +        reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
> +    return *this;
> +#else
>     #warning exception_ptr not yet implemented
>     printf("exception_ptr not yet implemented\n");
>     ::abort();
> -#endif  // __APPLE__
> +#endif
> }
> 
> nested_exception::nested_exception() _NOEXCEPT
> @@ -202,6 +240,7 @@
>     rethrow_exception(__ptr_);
> }
> 
> +#if !defined(__GLIBCXX__)
> 
> exception_ptr current_exception() _NOEXCEPT
> {
> @@ -212,24 +251,28 @@
>     exception_ptr ptr;
>     ptr.__ptr_ = __cxa_current_primary_exception();
>     return ptr;
> -#else  // __APPLE__
> +#else
>     #warning exception_ptr not yet implemented
>     printf("exception_ptr not yet implemented\n");
>     ::abort();
> -#endif  // __APPLE__
> +#endif
> }
> 
> +#endif  // !__GLIBCXX__
> +
> _LIBCPP_NORETURN
> void rethrow_exception(exception_ptr p)
> {
> #if HAVE_DEPENDENT_EH_ABI
>     __cxa_rethrow_primary_exception(p.__ptr_);
>     // if p.__ptr_ is NULL, above returns so we terminate
>     terminate();
> -#else  // __APPLE__
> +#elif defined(__GLIBCXX__)
> +    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
> +#else
>     #warning exception_ptr not yet implemented
>     printf("exception_ptr not yet implemented\n");
>     ::abort();
> -#endif  // __APPLE__
> +#endif
> }
> } // std
> <D1826.1.patch>_______________________________________________


The language lawyers are going to have a field-day with this code.  However I see no alternative to accomplish the task you are after.

Please commit.  Please svn update first and resolve conflicts.  This file changed since you filed this patch.  Sorry for the delay in the review.

Thanks,
Howard






More information about the cfe-commits mailing list