From 55819ce107beb662d2273dacd390271faf11c217 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sun, 24 Nov 2019 06:49:01 +0000 Subject: [PATCH] Move the libstdc++ code path to a separate file. We need to #include for this to work, but this brings in the public definition of `std::type_info` and, unfortunately, that breaks the private definition that we need in this compilation unit. --- CMakeLists.txt | 2 +- libstdcxx_current_primary_exception.cc | 19 +++++++++++++++++++ objcxx_eh.cc | 11 ----------- 3 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 libstdcxx_current_primary_exception.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index dddce40..1ff1234 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ if (WIN32) list(APPEND libobjc_CXX_SRCS eh_win32_msvc.cc) else () list(APPEND libobjc_C_SRCS eh_personality.c) - set(libobjcxx_CXX_SRCS objcxx_eh.cc) + set(libobjcxx_CXX_SRCS objcxx_eh.cc libstdcxx_current_primary_exception.cc) endif (WIN32) diff --git a/libstdcxx_current_primary_exception.cc b/libstdcxx_current_primary_exception.cc new file mode 100644 index 0000000..5bdd94e --- /dev/null +++ b/libstdcxx_current_primary_exception.cc @@ -0,0 +1,19 @@ +#include "visibility.h" +#include + +#ifdef __GLIBCXX__ +/** + * libsupc++ doesn't expose __cxa_current_primary_exception, so implement this + * using the libstdc++ wrapper. The exception pointer in the + * `std::exception_ptr` object is reference counted, so stealing it by poking + * at the pointer directly means that we acquire it with a reference count of + * 1. + */ +PRIVATE extern "C" void *__cxa_current_primary_exception() +{ + std::exception_ptr p = std::current_exception(); + void *obj = *(void**)&p; + *(void**)&p = nullptr; + return obj; +} +#endif diff --git a/objcxx_eh.cc b/objcxx_eh.cc index 6cea852..ade63cc 100644 --- a/objcxx_eh.cc +++ b/objcxx_eh.cc @@ -22,19 +22,8 @@ extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)); -#ifdef __GLIBCXX__ -#include -static void *__cxa_current_primary_exception() -{ - std::exception_ptr p = std::current_exception(); - void *obj = *(void**)&p; - *(void**)&p = nullptr; - return obj; -} -#else extern "C" void *__cxa_current_primary_exception(); -#endif using namespace __cxxabiv1;