Here is my attempt to fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68297. The resulting patch is a little bit long because I had to split <exception> and cxxabi.h include files. The former had to be split due to circular dependency that formed after including <typeinfo> in exception_ptr.h and the later is because of inability to include cxxabi.h in exception_ptr.h because it makes libstdc++/30586 to reappear again.
Comments are welcome. diff --git a/libcilkrts/runtime/except-gcc.h b/libcilkrts/runtime/except-gcc.h index 3ef4061..113fade 100644 --- a/libcilkrts/runtime/except-gcc.h +++ b/libcilkrts/runtime/except-gcc.h @@ -65,7 +65,7 @@ #endif #include <cilk/common.h> -#include <exception> +#include <bits/exception.h> #include <typeinfo> struct __cxa_exception; diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver index 8304dee..65866a3 100644 --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver @@ -179,6 +179,7 @@ CXXABI_2.0 { __cxa_free_exception; __cxa_free_dependent_exception; __cxa_get_exception_ptr; + __cxa_init_primary_exception; __cxa_get_globals; __cxa_get_globals_fast; __cxa_guard_abort; @@ -205,6 +206,7 @@ CXXABI_2.0 { # std::exception_ptr _ZNSt15__exception_ptr13exception_ptrC1Ev; _ZNSt15__exception_ptr13exception_ptrC2Ev; + _ZNSt15__exception_ptr13exception_ptrC1EPv; _ZNSt15__exception_ptr13exception_ptrC1ERKS0_; _ZNSt15__exception_ptr13exception_ptrC2ERKS0_; _ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE; diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 5c6b0fe..2425dca 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2152,6 +2152,13 @@ CXXABI_1.3.10 { } CXXABI_1.3.9; +CXXABI_1.3.11 { + + __cxa_init_primary_exception; + _ZNSt15__exception_ptr13exception_ptrC1EPv; + +} CXXABI_1.3.10; + # Symbols in the support library (libsupc++) supporting transactional memory. CXXABI_TM_1 { diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 4bc3354..8eee88b 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -201,8 +201,10 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++ bits_sup_headers = \ ${bits_sup_srcdir}/atomic_lockfree_defines.h \ ${bits_sup_srcdir}/cxxabi_forced.h \ + ${bits_sup_srcdir}/cxxabiv1.h \ ${bits_sup_srcdir}/exception_defines.h \ ${bits_sup_srcdir}/exception_ptr.h \ + ${bits_sup_srcdir}/exception.h \ ${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/nested_exception.h diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 1f255a9..18e6073 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -491,8 +491,10 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++ bits_sup_headers = \ ${bits_sup_srcdir}/atomic_lockfree_defines.h \ ${bits_sup_srcdir}/cxxabi_forced.h \ + ${bits_sup_srcdir}/cxxabiv1.h \ ${bits_sup_srcdir}/exception_defines.h \ ${bits_sup_srcdir}/exception_ptr.h \ + ${bits_sup_srcdir}/exception.h \ ${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/nested_exception.h diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am index b45b5ae..644e51e 100644 --- a/libstdc++-v3/libsupc++/Makefile.am +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -34,8 +34,8 @@ std_HEADERS = \ cxxabi.h exception initializer_list new typeinfo bits_HEADERS = \ - atomic_lockfree_defines.h cxxabi_forced.h \ - exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h + atomic_lockfree_defines.h cxxabi_forced.h cxxabiv1.h\ + exception_defines.h exception_ptr.h exception.h hash_bytes.h nested_exception.h headers = $(std_HEADERS) $(bits_HEADERS) diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index f3648ac..bbb837a 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -394,8 +394,8 @@ std_HEADERS = \ cxxabi.h exception initializer_list new typeinfo bits_HEADERS = \ - atomic_lockfree_defines.h cxxabi_forced.h \ - exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h + atomic_lockfree_defines.h cxxabi_forced.h cxxabiv1.h \ + exception_defines.h exception_ptr.h exception.h hash_bytes.h nested_exception.h headers = $(std_HEADERS) $(bits_HEADERS) @GLIBCXX_HOSTED_TRUE@c_sources = \ diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h index 11ff9e5..a33cc90 100644 --- a/libstdc++-v3/libsupc++/cxxabi.h +++ b/libstdc++-v3/libsupc++/cxxabi.h @@ -45,622 +45,11 @@ #pragma GCC visibility push(default) -#include <stddef.h> -#include <bits/c++config.h> -#include <bits/cxxabi_tweaks.h> #include <bits/cxxabi_forced.h> - -#ifndef _GLIBCXX_CDTOR_CALLABI -#define _GLIBCXX_CDTOR_CALLABI -#endif - -#ifdef __cplusplus -namespace __cxxabiv1 -{ - extern "C" - { -#endif - - typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); - - // Allocate array. - void* - __cxa_vec_new(size_t __element_count, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __constructor, - __cxa_cdtor_type __destructor); - - void* - __cxa_vec_new2(size_t __element_count, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __constructor, - __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), - void (*__dealloc) (void*)); - - void* - __cxa_vec_new3(size_t __element_count, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __constructor, - __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), - void (*__dealloc) (void*, size_t)); - - // Construct array. - __cxa_vec_ctor_return_type - __cxa_vec_ctor(void* __array_address, size_t __element_count, - size_t __element_size, __cxa_cdtor_type __constructor, - __cxa_cdtor_type __destructor); - - __cxa_vec_ctor_return_type - __cxa_vec_cctor(void* __dest_array, void* __src_array, - size_t __element_count, size_t __element_size, - __cxa_cdtor_return_type (*__constructor) (void*, void*), - __cxa_cdtor_type __destructor); - - // Destruct array. - void - __cxa_vec_dtor(void* __array_address, size_t __element_count, - size_t __element_size, __cxa_cdtor_type __destructor); - - void - __cxa_vec_cleanup(void* __array_address, size_t __element_count, size_t __s, - __cxa_cdtor_type __destructor) _GLIBCXX_NOTHROW; - - // Destruct and release array. - void - __cxa_vec_delete(void* __array_address, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __destructor); - - void - __cxa_vec_delete2(void* __array_address, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __destructor, - void (*__dealloc) (void*)); - - void - __cxa_vec_delete3(void* __array_address, size_t __element_size, - size_t __padding_size, __cxa_cdtor_type __destructor, - void (*__dealloc) (void*, size_t)); - - int - __cxa_guard_acquire(__guard*); - - void - __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW; - - void - __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW; - - // DSO destruction. - int - __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW; - - int - __cxa_finalize(void*); - - // TLS destruction. - int - __cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW; - - // Pure virtual functions. - void - __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); - - void - __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); - - // Exception handling auxiliary. - void - __cxa_bad_cast() __attribute__((__noreturn__)); - - void - __cxa_bad_typeid() __attribute__((__noreturn__)); - - void - __cxa_throw_bad_array_new_length() __attribute__((__noreturn__)); - - /** - * @brief Demangling routine. - * ABI-mandated entry point in the C++ runtime library for demangling. - * - * @param __mangled_name A NUL-terminated character string - * containing the name to be demangled. - * - * @param __output_buffer A region of memory, allocated with - * malloc, of @a *__length bytes, into which the demangled name is - * stored. If @a __output_buffer is not long enough, it is - * expanded using realloc. @a __output_buffer may instead be NULL; - * in that case, the demangled name is placed in a region of memory - * allocated with malloc. - * - * @param __length If @a __length is non-NULL, the length of the - * buffer containing the demangled name is placed in @a *__length. - * - * @param __status @a *__status is set to one of the following values: - * 0: The demangling operation succeeded. - * -1: A memory allocation failure occurred. - * -2: @a mangled_name is not a valid name under the C++ ABI mangling rules. - * -3: One of the arguments is invalid. - * - * @return A pointer to the start of the NUL-terminated demangled - * name, or NULL if the demangling fails. The caller is - * responsible for deallocating this memory using @c free. - * - * The demangling is performed using the C++ ABI mangling rules, - * with GNU extensions. For example, this function is used in - * __gnu_cxx::__verbose_terminate_handler. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html - * for other examples of use. - * - * @note The same demangling functionality is available via - * libiberty (@c <libiberty/demangle.h> and @c libiberty.a) in GCC - * 3.1 and later, but that requires explicit installation (@c - * --enable-install-libiberty) and uses a different API, although - * the ABI is unchanged. - */ - char* - __cxa_demangle(const char* __mangled_name, char* __output_buffer, - size_t* __length, int* __status); - -#ifdef __cplusplus - } -} // namespace __cxxabiv1 -#endif +#include <bits/cxxabiv1.h> #ifdef __cplusplus -#include <typeinfo> - -namespace __cxxabiv1 -{ - // Type information for int, float etc. - class __fundamental_type_info : public std::type_info - { - public: - explicit - __fundamental_type_info(const char* __n) : std::type_info(__n) { } - - virtual - ~__fundamental_type_info(); - }; - - // Type information for array objects. - class __array_type_info : public std::type_info - { - public: - explicit - __array_type_info(const char* __n) : std::type_info(__n) { } - - virtual - ~__array_type_info(); - }; - - // Type information for functions (both member and non-member). - class __function_type_info : public std::type_info - { - public: - explicit - __function_type_info(const char* __n) : std::type_info(__n) { } - - virtual - ~__function_type_info(); - - protected: - // Implementation defined member function. - virtual bool - __is_function_p() const; - }; - - // Type information for enumerations. - class __enum_type_info : public std::type_info - { - public: - explicit - __enum_type_info(const char* __n) : std::type_info(__n) { } - - virtual - ~__enum_type_info(); - }; - - // Common type information for simple pointers and pointers to member. - class __pbase_type_info : public std::type_info - { - public: - unsigned int __flags; // Qualification of the target object. - const std::type_info* __pointee; // Type of pointed to object. - - explicit - __pbase_type_info(const char* __n, int __quals, - const std::type_info* __type) - : std::type_info(__n), __flags(__quals), __pointee(__type) - { } - - virtual - ~__pbase_type_info(); - - // Implementation defined type. - enum __masks - { - __const_mask = 0x1, - __volatile_mask = 0x2, - __restrict_mask = 0x4, - __incomplete_mask = 0x8, - __incomplete_class_mask = 0x10, - __transaction_safe_mask = 0x20 - }; - - protected: - __pbase_type_info(const __pbase_type_info&); - - __pbase_type_info& - operator=(const __pbase_type_info&); - - // Implementation defined member functions. - virtual bool - __do_catch(const std::type_info* __thr_type, void** __thr_obj, - unsigned int __outer) const; - - inline virtual bool - __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, - unsigned __outer) const; - }; - - inline bool __pbase_type_info:: - __pointer_catch (const __pbase_type_info *thrown_type, - void **thr_obj, - unsigned outer) const - { - return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); - } - - // Type information for simple pointers. - class __pointer_type_info : public __pbase_type_info - { - public: - explicit - __pointer_type_info(const char* __n, int __quals, - const std::type_info* __type) - : __pbase_type_info (__n, __quals, __type) { } - - - virtual - ~__pointer_type_info(); - - protected: - // Implementation defined member functions. - virtual bool - __is_pointer_p() const; - - virtual bool - __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, - unsigned __outer) const; - }; - - class __class_type_info; - - // Type information for a pointer to member variable. - class __pointer_to_member_type_info : public __pbase_type_info - { - public: - __class_type_info* __context; // Class of the member. - - explicit - __pointer_to_member_type_info(const char* __n, int __quals, - const std::type_info* __type, - __class_type_info* __klass) - : __pbase_type_info(__n, __quals, __type), __context(__klass) { } - - virtual - ~__pointer_to_member_type_info(); - - protected: - __pointer_to_member_type_info(const __pointer_to_member_type_info&); - - __pointer_to_member_type_info& - operator=(const __pointer_to_member_type_info&); - - // Implementation defined member function. - virtual bool - __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, - unsigned __outer) const; - }; - - // Helper class for __vmi_class_type. - class __base_class_type_info - { - public: - const __class_type_info* __base_type; // Base class type. -#ifdef _GLIBCXX_LLP64 - long long __offset_flags; // Offset and info. -#else - long __offset_flags; // Offset and info. -#endif - - enum __offset_flags_masks - { - __virtual_mask = 0x1, - __public_mask = 0x2, - __hwm_bit = 2, - __offset_shift = 8 // Bits to shift offset. - }; - - // Implementation defined member functions. - bool - __is_virtual_p() const - { return __offset_flags & __virtual_mask; } - - bool - __is_public_p() const - { return __offset_flags & __public_mask; } - - ptrdiff_t - __offset() const - { - // This shift, being of a signed type, is implementation - // defined. GCC implements such shifts as arithmetic, which is - // what we want. - return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift; - } - }; - - // Type information for a class. - class __class_type_info : public std::type_info - { - public: - explicit - __class_type_info (const char *__n) : type_info(__n) { } - - virtual - ~__class_type_info (); - - // Implementation defined types. - // The type sub_kind tells us about how a base object is contained - // within a derived object. We often do this lazily, hence the - // UNKNOWN value. At other times we may use NOT_CONTAINED to mean - // not publicly contained. - enum __sub_kind - { - // We have no idea. - __unknown = 0, - - // Not contained within us (in some circumstances this might - // mean not contained publicly) - __not_contained, - - // Contained ambiguously. - __contained_ambig, - - // Via a virtual path. - __contained_virtual_mask = __base_class_type_info::__virtual_mask, - - // Via a public path. - __contained_public_mask = __base_class_type_info::__public_mask, - - // Contained within us. - __contained_mask = 1 << __base_class_type_info::__hwm_bit, - - __contained_private = __contained_mask, - __contained_public = __contained_mask | __contained_public_mask - }; - - struct __upcast_result; - struct __dyncast_result; - - protected: - // Implementation defined member functions. - virtual bool - __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; - - virtual bool - __do_catch(const type_info* __thr_type, void** __thr_obj, - unsigned __outer) const; - - public: - // Helper for upcast. See if DST is us, or one of our bases. - // Return false if not found, true if found. - virtual bool - __do_upcast(const __class_type_info* __dst, const void* __obj, - __upcast_result& __restrict __result) const; - - // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly - // within OBJ_PTR. OBJ_PTR points to a base object of our type, - // which is the destination type. SRC2DST indicates how SRC - // objects might be contained within this type. If SRC_PTR is one - // of our SRC_TYPE bases, indicate the virtuality. Returns - // not_contained for non containment or private containment. - inline __sub_kind - __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, - const __class_type_info* __src_type, - const void* __src_ptr) const; - - // Helper for dynamic cast. ACCESS_PATH gives the access from the - // most derived object to this base. DST_TYPE indicates the - // desired type we want. OBJ_PTR points to a base of our type - // within the complete object. SRC_TYPE indicates the static type - // started from and SRC_PTR points to that base within the most - // derived object. Fill in RESULT with what we find. Return true - // if we have located an ambiguous match. - virtual bool - __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, - const __class_type_info* __dst_type, const void* __obj_ptr, - const __class_type_info* __src_type, const void* __src_ptr, - __dyncast_result& __result) const; - - // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE - // bases are inherited by the type started from -- which is not - // necessarily the current type. The current type will be a base - // of the destination type. OBJ_PTR points to the current base. - virtual __sub_kind - __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, - const __class_type_info* __src_type, - const void* __src_ptr) const; - }; - - // Type information for a class with a single non-virtual base. - class __si_class_type_info : public __class_type_info - { - public: - const __class_type_info* __base_type; - - explicit - __si_class_type_info(const char *__n, const __class_type_info *__base) - : __class_type_info(__n), __base_type(__base) { } - - virtual - ~__si_class_type_info(); - - protected: - __si_class_type_info(const __si_class_type_info&); - - __si_class_type_info& - operator=(const __si_class_type_info&); - - // Implementation defined member functions. - virtual bool - __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, - const __class_type_info* __dst_type, const void* __obj_ptr, - const __class_type_info* __src_type, const void* __src_ptr, - __dyncast_result& __result) const; - - virtual __sub_kind - __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, - const __class_type_info* __src_type, - const void* __sub_ptr) const; - - virtual bool - __do_upcast(const __class_type_info*__dst, const void*__obj, - __upcast_result& __restrict __result) const; - }; - - // Type information for a class with multiple and/or virtual bases. - class __vmi_class_type_info : public __class_type_info - { - public: - unsigned int __flags; // Details about the class hierarchy. - unsigned int __base_count; // Number of direct bases. - - // The array of bases uses the trailing array struct hack so this - // class is not constructable with a normal constructor. It is - // internally generated by the compiler. - __base_class_type_info __base_info[1]; // Array of bases. - - explicit - __vmi_class_type_info(const char* __n, int ___flags) - : __class_type_info(__n), __flags(___flags), __base_count(0) { } - - virtual - ~__vmi_class_type_info(); - - // Implementation defined types. - enum __flags_masks - { - __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. - __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. - __flags_unknown_mask = 0x10 - }; - - protected: - // Implementation defined member functions. - virtual bool - __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, - const __class_type_info* __dst_type, const void* __obj_ptr, - const __class_type_info* __src_type, const void* __src_ptr, - __dyncast_result& __result) const; - - virtual __sub_kind - __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, - const __class_type_info* __src_type, - const void* __src_ptr) const; - - virtual bool - __do_upcast(const __class_type_info* __dst, const void* __obj, - __upcast_result& __restrict __result) const; - }; - - // Exception handling forward declarations. - struct __cxa_exception; - struct __cxa_refcounted_exception; - struct __cxa_dependent_exception; - struct __cxa_eh_globals; - - extern "C" - { - // Dynamic cast runtime. - - // src2dst has the following possible values - // >-1: src_type is a unique public non-virtual base of dst_type - // dst_ptr + src2dst == src_ptr - // -1: unspecified relationship - // -2: src_type is not a public base of dst_type - // -3: src_type is a multiple public non-virtual base of dst_type - void* - __dynamic_cast(const void* __src_ptr, // Starting object. - const __class_type_info* __src_type, // Static type of object. - const __class_type_info* __dst_type, // Desired target type. - ptrdiff_t __src2dst); // How src and dst are related. - - - // Exception handling runtime. - - // The __cxa_eh_globals for the current thread can be obtained by using - // either of the following functions. The "fast" version assumes at least - // one prior call of __cxa_get_globals has been made from the current - // thread, so no initialization is necessary. - __cxa_eh_globals* - __cxa_get_globals() _GLIBCXX_NOTHROW __attribute__ ((__const__)); - - __cxa_eh_globals* - __cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__)); - - // Allocate memory for the primary exception plus the thrown object. - void* - __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW; - - // Free the space allocated for the primary exception. - void - __cxa_free_exception(void*) _GLIBCXX_NOTHROW; - - // Throw the exception. - void - __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) - __attribute__((__noreturn__)); - - // Used to implement exception handlers. - void* - __cxa_get_exception_ptr(void*) _GLIBCXX_NOTHROW __attribute__ ((__pure__)); - - void* - __cxa_begin_catch(void*) _GLIBCXX_NOTHROW; - - void - __cxa_end_catch(); - - void - __cxa_rethrow() __attribute__((__noreturn__)); - - // Returns the type_info for the currently handled exception [15.3/8], or - // null if there is none. - std::type_info* - __cxa_current_exception_type() _GLIBCXX_NOTHROW __attribute__ ((__pure__)); - - // GNU Extensions. - - // Allocate memory for a dependent exception. - __cxa_dependent_exception* - __cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW; - - // Free the space allocated for the dependent exception. - void - __cxa_free_dependent_exception(__cxa_dependent_exception*) _GLIBCXX_NOTHROW; - - } // extern "C" - - // A magic placeholder class that can be caught by reference - // to recognize foreign exceptions. - class __foreign_exception - { - virtual ~__foreign_exception() throw(); - virtual void __pure_dummy() = 0; // prevent catch by value - }; - -} // namespace __cxxabiv1 - /** @namespace abi * @brief The cross-vendor C++ Application Binary Interface. A * namespace alias to __cxxabiv1, but user programs should use the diff --git a/libstdc++-v3/libsupc++/cxxabiv1.h b/libstdc++-v3/libsupc++/cxxabiv1.h new file mode 100644 index 0000000..7f67da5 --- /dev/null +++ b/libstdc++-v3/libsupc++/cxxabiv1.h @@ -0,0 +1,631 @@ +#ifndef _CXXABIV1_H +#define _CXXABIV1_H + +#pragma GCC system_header + +#include <stddef.h> +#include <bits/c++config.h> +#include <bits/cxxabi_tweaks.h> + +#ifndef _GLIBCXX_CDTOR_CALLABI +#define _GLIBCXX_CDTOR_CALLABI +#define _GLIBCXX_HAVE_CDTOR_CALLABI 0 +#else +#define _GLIBCXX_HAVE_CDTOR_CALLABI 1 +#endif + +#ifdef __cplusplus +namespace __cxxabiv1 +{ + extern "C" + { +#endif + + typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); + + // Allocate array. + void* + __cxa_vec_new(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor); + + void* + __cxa_vec_new2(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), + void (*__dealloc) (void*)); + + void* + __cxa_vec_new3(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), + void (*__dealloc) (void*, size_t)); + + // Construct array. + __cxa_vec_ctor_return_type + __cxa_vec_ctor(void* __array_address, size_t __element_count, + size_t __element_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor); + + __cxa_vec_ctor_return_type + __cxa_vec_cctor(void* __dest_array, void* __src_array, + size_t __element_count, size_t __element_size, + __cxa_cdtor_return_type (*__constructor) (void*, void*), + __cxa_cdtor_type __destructor); + + // Destruct array. + void + __cxa_vec_dtor(void* __array_address, size_t __element_count, + size_t __element_size, __cxa_cdtor_type __destructor); + + void + __cxa_vec_cleanup(void* __array_address, size_t __element_count, size_t __s, + __cxa_cdtor_type __destructor) _GLIBCXX_NOTHROW; + + // Destruct and release array. + void + __cxa_vec_delete(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor); + + void + __cxa_vec_delete2(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor, + void (*__dealloc) (void*)); + + void + __cxa_vec_delete3(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor, + void (*__dealloc) (void*, size_t)); + + int + __cxa_guard_acquire(__guard*); + + void + __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW; + + void + __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW; + + // DSO destruction. + int + __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW; + + int + __cxa_finalize(void*); + + // TLS destruction. + int + __cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW; + + // Pure virtual functions. + void + __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); + + void + __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); + + // Exception handling auxiliary. + void + __cxa_bad_cast() __attribute__((__noreturn__)); + + void + __cxa_bad_typeid() __attribute__((__noreturn__)); + + void + __cxa_throw_bad_array_new_length() __attribute__((__noreturn__)); + + /** + * @brief Demangling routine. + * ABI-mandated entry point in the C++ runtime library for demangling. + * + * @param __mangled_name A NUL-terminated character string + * containing the name to be demangled. + * + * @param __output_buffer A region of memory, allocated with + * malloc, of @a *__length bytes, into which the demangled name is + * stored. If @a __output_buffer is not long enough, it is + * expanded using realloc. @a __output_buffer may instead be NULL; + * in that case, the demangled name is placed in a region of memory + * allocated with malloc. + * + * @param __length If @a __length is non-NULL, the length of the + * buffer containing the demangled name is placed in @a *__length. + * + * @param __status @a *__status is set to one of the following values: + * 0: The demangling operation succeeded. + * -1: A memory allocation failure occurred. + * -2: @a mangled_name is not a valid name under the C++ ABI mangling rules. + * -3: One of the arguments is invalid. + * + * @return A pointer to the start of the NUL-terminated demangled + * name, or NULL if the demangling fails. The caller is + * responsible for deallocating this memory using @c free. + * + * The demangling is performed using the C++ ABI mangling rules, + * with GNU extensions. For example, this function is used in + * __gnu_cxx::__verbose_terminate_handler. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html + * for other examples of use. + * + * @note The same demangling functionality is available via + * libiberty (@c <libiberty/demangle.h> and @c libiberty.a) in GCC + * 3.1 and later, but that requires explicit installation (@c + * --enable-install-libiberty) and uses a different API, although + * the ABI is unchanged. + */ + char* + __cxa_demangle(const char* __mangled_name, char* __output_buffer, + size_t* __length, int* __status); + +#ifdef __cplusplus + } +} // namespace __cxxabiv1 +#endif + +#ifdef __cplusplus + +#include <typeinfo> + +namespace __cxxabiv1 +{ + // Type information for int, float etc. + class __fundamental_type_info : public std::type_info + { + public: + explicit + __fundamental_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__fundamental_type_info(); + }; + + // Type information for array objects. + class __array_type_info : public std::type_info + { + public: + explicit + __array_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__array_type_info(); + }; + + // Type information for functions (both member and non-member). + class __function_type_info : public std::type_info + { + public: + explicit + __function_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__function_type_info(); + + protected: + // Implementation defined member function. + virtual bool + __is_function_p() const; + }; + + // Type information for enumerations. + class __enum_type_info : public std::type_info + { + public: + explicit + __enum_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__enum_type_info(); + }; + + // Common type information for simple pointers and pointers to member. + class __pbase_type_info : public std::type_info + { + public: + unsigned int __flags; // Qualification of the target object. + const std::type_info* __pointee; // Type of pointed to object. + + explicit + __pbase_type_info(const char* __n, int __quals, + const std::type_info* __type) + : std::type_info(__n), __flags(__quals), __pointee(__type) + { } + + virtual + ~__pbase_type_info(); + + // Implementation defined type. + enum __masks + { + __const_mask = 0x1, + __volatile_mask = 0x2, + __restrict_mask = 0x4, + __incomplete_mask = 0x8, + __incomplete_class_mask = 0x10, + __transaction_safe_mask = 0x20 + }; + + protected: + __pbase_type_info(const __pbase_type_info&); + + __pbase_type_info& + operator=(const __pbase_type_info&); + + // Implementation defined member functions. + virtual bool + __do_catch(const std::type_info* __thr_type, void** __thr_obj, + unsigned int __outer) const; + + inline virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + inline bool __pbase_type_info:: + __pointer_catch (const __pbase_type_info *thrown_type, + void **thr_obj, + unsigned outer) const + { + return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); + } + + // Type information for simple pointers. + class __pointer_type_info : public __pbase_type_info + { + public: + explicit + __pointer_type_info(const char* __n, int __quals, + const std::type_info* __type) + : __pbase_type_info (__n, __quals, __type) { } + + + virtual + ~__pointer_type_info(); + + protected: + // Implementation defined member functions. + virtual bool + __is_pointer_p() const; + + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + class __class_type_info; + + // Type information for a pointer to member variable. + class __pointer_to_member_type_info : public __pbase_type_info + { + public: + __class_type_info* __context; // Class of the member. + + explicit + __pointer_to_member_type_info(const char* __n, int __quals, + const std::type_info* __type, + __class_type_info* __klass) + : __pbase_type_info(__n, __quals, __type), __context(__klass) { } + + virtual + ~__pointer_to_member_type_info(); + + protected: + __pointer_to_member_type_info(const __pointer_to_member_type_info&); + + __pointer_to_member_type_info& + operator=(const __pointer_to_member_type_info&); + + // Implementation defined member function. + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Helper class for __vmi_class_type. + class __base_class_type_info + { + public: + const __class_type_info* __base_type; // Base class type. +#ifdef _GLIBCXX_LLP64 + long long __offset_flags; // Offset and info. +#else + long __offset_flags; // Offset and info. +#endif + + enum __offset_flags_masks + { + __virtual_mask = 0x1, + __public_mask = 0x2, + __hwm_bit = 2, + __offset_shift = 8 // Bits to shift offset. + }; + + // Implementation defined member functions. + bool + __is_virtual_p() const + { return __offset_flags & __virtual_mask; } + + bool + __is_public_p() const + { return __offset_flags & __public_mask; } + + ptrdiff_t + __offset() const + { + // This shift, being of a signed type, is implementation + // defined. GCC implements such shifts as arithmetic, which is + // what we want. + return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift; + } + }; + + // Type information for a class. + class __class_type_info : public std::type_info + { + public: + explicit + __class_type_info (const char *__n) : type_info(__n) { } + + virtual + ~__class_type_info (); + + // Implementation defined types. + // The type sub_kind tells us about how a base object is contained + // within a derived object. We often do this lazily, hence the + // UNKNOWN value. At other times we may use NOT_CONTAINED to mean + // not publicly contained. + enum __sub_kind + { + // We have no idea. + __unknown = 0, + + // Not contained within us (in some circumstances this might + // mean not contained publicly) + __not_contained, + + // Contained ambiguously. + __contained_ambig, + + // Via a virtual path. + __contained_virtual_mask = __base_class_type_info::__virtual_mask, + + // Via a public path. + __contained_public_mask = __base_class_type_info::__public_mask, + + // Contained within us. + __contained_mask = 1 << __base_class_type_info::__hwm_bit, + + __contained_private = __contained_mask, + __contained_public = __contained_mask | __contained_public_mask + }; + + struct __upcast_result; + struct __dyncast_result; + + protected: + // Implementation defined member functions. + virtual bool + __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; + + virtual bool + __do_catch(const type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + + public: + // Helper for upcast. See if DST is us, or one of our bases. + // Return false if not found, true if found. + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + + // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly + // within OBJ_PTR. OBJ_PTR points to a base object of our type, + // which is the destination type. SRC2DST indicates how SRC + // objects might be contained within this type. If SRC_PTR is one + // of our SRC_TYPE bases, indicate the virtuality. Returns + // not_contained for non containment or private containment. + inline __sub_kind + __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + // Helper for dynamic cast. ACCESS_PATH gives the access from the + // most derived object to this base. DST_TYPE indicates the + // desired type we want. OBJ_PTR points to a base of our type + // within the complete object. SRC_TYPE indicates the static type + // started from and SRC_PTR points to that base within the most + // derived object. Fill in RESULT with what we find. Return true + // if we have located an ambiguous match. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE + // bases are inherited by the type started from -- which is not + // necessarily the current type. The current type will be a base + // of the destination type. OBJ_PTR points to the current base. + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + }; + + // Type information for a class with a single non-virtual base. + class __si_class_type_info : public __class_type_info + { + public: + const __class_type_info* __base_type; + + explicit + __si_class_type_info(const char *__n, const __class_type_info *__base) + : __class_type_info(__n), __base_type(__base) { } + + virtual + ~__si_class_type_info(); + + protected: + __si_class_type_info(const __si_class_type_info&); + + __si_class_type_info& + operator=(const __si_class_type_info&); + + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __sub_ptr) const; + + virtual bool + __do_upcast(const __class_type_info*__dst, const void*__obj, + __upcast_result& __restrict __result) const; + }; + + // Type information for a class with multiple and/or virtual bases. + class __vmi_class_type_info : public __class_type_info + { + public: + unsigned int __flags; // Details about the class hierarchy. + unsigned int __base_count; // Number of direct bases. + + // The array of bases uses the trailing array struct hack so this + // class is not constructable with a normal constructor. It is + // internally generated by the compiler. + __base_class_type_info __base_info[1]; // Array of bases. + + explicit + __vmi_class_type_info(const char* __n, int ___flags) + : __class_type_info(__n), __flags(___flags), __base_count(0) { } + + virtual + ~__vmi_class_type_info(); + + // Implementation defined types. + enum __flags_masks + { + __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. + __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. + __flags_unknown_mask = 0x10 + }; + + protected: + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + }; + + // Exception handling forward declarations. + struct __cxa_exception; + struct __cxa_refcounted_exception; + struct __cxa_dependent_exception; + struct __cxa_eh_globals; + + extern "C" + { + // Dynamic cast runtime. + + // src2dst has the following possible values + // >-1: src_type is a unique public non-virtual base of dst_type + // dst_ptr + src2dst == src_ptr + // -1: unspecified relationship + // -2: src_type is not a public base of dst_type + // -3: src_type is a multiple public non-virtual base of dst_type + void* + __dynamic_cast(const void* __src_ptr, // Starting object. + const __class_type_info* __src_type, // Static type of object. + const __class_type_info* __dst_type, // Desired target type. + ptrdiff_t __src2dst); // How src and dst are related. + + + // Exception handling runtime. + + // The __cxa_eh_globals for the current thread can be obtained by using + // either of the following functions. The "fast" version assumes at least + // one prior call of __cxa_get_globals has been made from the current + // thread, so no initialization is necessary. + __cxa_eh_globals* + __cxa_get_globals() _GLIBCXX_NOTHROW __attribute__ ((__const__)); + + __cxa_eh_globals* + __cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__)); + + // Allocate memory for the primary exception plus the thrown object. + void* + __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW; + + // Free the space allocated for the primary exception. + void + __cxa_free_exception(void*) _GLIBCXX_NOTHROW; + + // Throw the exception. + void + __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) + __attribute__((__noreturn__)); + + // Used to implement exception handlers. + void* + __cxa_get_exception_ptr(void*) _GLIBCXX_NOTHROW __attribute__ ((__pure__)); + + void* + __cxa_begin_catch(void*) _GLIBCXX_NOTHROW; + + void + __cxa_end_catch(); + + void + __cxa_rethrow() __attribute__((__noreturn__)); + + // Returns the type_info for the currently handled exception [15.3/8], or + // null if there is none. + std::type_info* + __cxa_current_exception_type() _GLIBCXX_NOTHROW __attribute__ ((__pure__)); + + // GNU Extensions. + + // Allocate memory for a dependent exception. + __cxa_dependent_exception* + __cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW; + + // Free the space allocated for the dependent exception. + void + __cxa_free_dependent_exception(__cxa_dependent_exception*) _GLIBCXX_NOTHROW; + + // Initialize exception + __cxa_refcounted_exception* + __cxa_init_primary_exception(void *object, const std::type_info *tinfo, + void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) _GLIBCXX_NOTHROW; + + } // extern "C" + + // A magic placeholder class that can be caught by reference + // to recognize foreign exceptions. + class __foreign_exception + { + virtual ~__foreign_exception() throw(); + virtual void __pure_dummy() = 0; // prevent catch by value + }; + +} // namespace __cxxabiv1 + +#endif // __cplusplus + +#endif // _CXXABIV1_H diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 9aac218..b368f8a 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -55,6 +55,22 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) #endif } +extern "C" __cxa_refcounted_exception* +__cxxabiv1::__cxa_init_primary_exception(void *obj, const std::type_info *tinfo, + void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) +{ + __cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_obj (obj); + header->referenceCount = 0; + header->exc.exceptionType = tinfo; + header->exc.exceptionDestructor = dest; + header->exc.unexpectedHandler = std::get_unexpected (); + header->exc.terminateHandler = std::get_terminate (); + __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class); + header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup; + + return header; +} extern "C" void __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, @@ -64,17 +80,10 @@ __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, __cxa_eh_globals *globals = __cxa_get_globals (); globals->uncaughtExceptions += 1; - // Definitely a primary. - __cxa_refcounted_exception *header - = __get_refcounted_exception_header_from_obj (obj); + __cxa_refcounted_exception *header = + __cxa_init_primary_exception(obj, tinfo, dest); header->referenceCount = 1; - header->exc.exceptionType = tinfo; - header->exc.exceptionDestructor = dest; - header->exc.unexpectedHandler = std::get_unexpected (); - header->exc.terminateHandler = std::get_terminate (); - __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class); - header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup; #ifdef __USING_SJLJ_EXCEPTIONS__ _Unwind_SjLj_RaiseException (&header->exc.unwindHeader); diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index 63631f6..6f8b596 100644 --- a/libstdc++-v3/libsupc++/exception +++ b/libstdc++-v3/libsupc++/exception @@ -34,135 +34,7 @@ #pragma GCC visibility push(default) -#include <bits/c++config.h> -#include <bits/atomic_lockfree_defines.h> - -extern "C++" { - -namespace std -{ - /** - * @defgroup exceptions Exceptions - * @ingroup diagnostics - * - * Classes and functions for reporting errors via exception classes. - * @{ - */ - - /** - * @brief Base class for all library exceptions. - * - * This is the base class for all exceptions thrown by the standard - * library, and by certain language expressions. You are free to derive - * your own %exception classes, or use a different hierarchy, or to - * throw non-class data (e.g., fundamental types). - */ - class exception - { - public: - exception() _GLIBCXX_USE_NOEXCEPT { } - virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; - - /** Returns a C-style character string describing the general cause - * of the current error. */ - virtual const char* - what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; - }; - - /** If an %exception is thrown which is not listed in a function's - * %exception specification, one of these may be thrown. */ - class bad_exception : public exception - { - public: - bad_exception() _GLIBCXX_USE_NOEXCEPT { } - - // 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; - }; - - /// If you write a replacement %terminate handler, it must be of this type. - typedef void (*terminate_handler) (); - - /// If you write a replacement %unexpected handler, it must be of this type. - typedef void (*unexpected_handler) (); - - /// Takes a new handler function as an argument, returns the old function. - terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT; - -#if __cplusplus >= 201103L - /// Return the current terminate handler. - terminate_handler get_terminate() noexcept; -#endif - - /** The runtime will call this function if %exception handling must be - * abandoned for any reason. It can also be called by the user. */ - void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__)); - - /// Takes a new handler function as an argument, returns the old function. - unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT; - -#if __cplusplus >= 201103L - /// Return the current unexpected handler. - unexpected_handler get_unexpected() noexcept; -#endif - - /** The runtime will call this function if an %exception is thrown which - * violates the function's %exception specification. */ - void unexpected() __attribute__ ((__noreturn__)); - - /** [18.6.4]/1: 'Returns true after completing evaluation of a - * throw-expression until either completing initialization of the - * exception-declaration in the matching handler or entering @c unexpected() - * due to the throw; or after entering @c terminate() for any reason - * other than an explicit call to @c terminate(). [Note: This includes - * stack unwinding [15.2]. end note]' - * - * 2: 'When @c uncaught_exception() is true, throwing an - * %exception can result in a call of @c terminate() - * (15.5.1).' - */ - bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); - -#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++98 -#define __cpp_lib_uncaught_exceptions 201411 - /// The number of uncaught exceptions. - int uncaught_exceptions() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); -#endif - - // @} group exceptions -} // namespace std - -namespace __gnu_cxx -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - /** - * @brief A replacement for the standard terminate_handler which - * prints more information about the terminating exception (if any) - * on stderr. - * - * @ingroup exceptions - * - * Call - * @code - * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) - * @endcode - * to use. For more info, see - * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html - * - * In 3.4 and later, this is on by default. - */ - void __verbose_terminate_handler(); - -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace - -} // extern "C++" +#include <bits/exception.h> #pragma GCC visibility pop diff --git a/libstdc++-v3/libsupc++/exception.h b/libstdc++-v3/libsupc++/exception.h new file mode 100644 index 0000000..bc1b8c8 --- /dev/null +++ b/libstdc++-v3/libsupc++/exception.h @@ -0,0 +1,163 @@ +// Exception Handling support header for -*- C++ -*- + +// Copyright (C) 1995-2016 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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. +// +// GCC 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 exception + * This is a Standard C++ Library header. + */ + +#ifndef __EXCEPTION_H +#define __EXCEPTION_H + +#include <bits/c++config.h> +#include <bits/atomic_lockfree_defines.h> + +extern "C++" { + +namespace std +{ + /** + * @defgroup exceptions Exceptions + * @ingroup diagnostics + * + * Classes and functions for reporting errors via exception classes. + * @{ + */ + + /** + * @brief Base class for all library exceptions. + * + * This is the base class for all exceptions thrown by the standard + * library, and by certain language expressions. You are free to derive + * your own %exception classes, or use a different hierarchy, or to + * throw non-class data (e.g., fundamental types). + */ + class exception + { + public: + exception() _GLIBCXX_USE_NOEXCEPT { } + virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; + + /** Returns a C-style character string describing the general cause + * of the current error. */ + virtual const char* + what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; + }; + + /** If an %exception is thrown which is not listed in a function's + * %exception specification, one of these may be thrown. */ + class bad_exception : public exception + { + public: + bad_exception() _GLIBCXX_USE_NOEXCEPT { } + + // 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; + }; + + /// If you write a replacement %terminate handler, it must be of this type. + typedef void (*terminate_handler) (); + + /// If you write a replacement %unexpected handler, it must be of this type. + typedef void (*unexpected_handler) (); + + /// Takes a new handler function as an argument, returns the old function. + terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT; + +#if __cplusplus >= 201103L + /// Return the current terminate handler. + terminate_handler get_terminate() noexcept; +#endif + + /** The runtime will call this function if %exception handling must be + * abandoned for any reason. It can also be called by the user. */ + void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__)); + + /// Takes a new handler function as an argument, returns the old function. + unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT; + +#if __cplusplus >= 201103L + /// Return the current unexpected handler. + unexpected_handler get_unexpected() noexcept; +#endif + + /** The runtime will call this function if an %exception is thrown which + * violates the function's %exception specification. */ + void unexpected() __attribute__ ((__noreturn__)); + + /** [18.6.4]/1: 'Returns true after completing evaluation of a + * throw-expression until either completing initialization of the + * exception-declaration in the matching handler or entering @c unexpected() + * due to the throw; or after entering @c terminate() for any reason + * other than an explicit call to @c terminate(). [Note: This includes + * stack unwinding [15.2]. end note]' + * + * 2: 'When @c uncaught_exception() is true, throwing an + * %exception can result in a call of @c terminate() + * (15.5.1).' + */ + bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); + +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++98 +#define __cpp_lib_uncaught_exceptions 201411 + /// The number of uncaught exceptions. + int uncaught_exceptions() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); +#endif + + // @} group exceptions +} // namespace std + +namespace __gnu_cxx +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief A replacement for the standard terminate_handler which + * prints more information about the terminating exception (if any) + * on stderr. + * + * @ingroup exceptions + * + * Call + * @code + * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) + * @endcode + * to use. For more info, see + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html + * + * In 3.4 and later, this is on by default. + */ + void __verbose_terminate_handler(); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +} // extern "C++" + +#endif diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index 783e539..6127b00 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -35,6 +35,9 @@ #include <bits/c++config.h> #include <bits/exception_defines.h> +#include <typeinfo> +#include <new> +#include <bits/cxxabiv1.h> #if ATOMIC_INT_LOCK_FREE < 2 # error This platform does not support exception propagation. @@ -62,6 +65,8 @@ namespace std * value. */ exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; + template<typename _Ex> + exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; /// Throw the object pointed to by the exception_ptr. void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); @@ -87,6 +92,8 @@ namespace std friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; friend void std::rethrow_exception(exception_ptr); + template<typename _Ex> + friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; public: exception_ptr() _GLIBCXX_USE_NOEXCEPT; @@ -162,8 +169,12 @@ namespace std swap(exception_ptr& __lhs, exception_ptr& __rhs) { __lhs.swap(__rhs); } - } // namespace __exception_ptr + template<typename _Ex> + static void dest_thunk(void* x) { + reinterpret_cast<_Ex*>(x)->_Ex::~_Ex(); + } + } // namespace __exception_ptr /// Obtain an exception_ptr pointing to a copy of the supplied object. template<typename _Ex> @@ -173,7 +184,15 @@ namespace std #if __cpp_exceptions try { - throw __ex; +#if __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI + void *e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); + (void)__cxxabiv1::__cxa_init_primary_exception(e, &typeid(__ex), + __exception_ptr::dest_thunk<_Ex>); + new (e) _Ex(__ex); + return exception_ptr(e); +#else + throw __ex; +#endif } catch(...) { diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo index baedf01..1c5ccc5 100644 --- a/libstdc++-v3/libsupc++/typeinfo +++ b/libstdc++-v3/libsupc++/typeinfo @@ -31,7 +31,7 @@ #pragma GCC system_header -#include <exception> +#include <bits/exception.h> #if __cplusplus >= 201103L #include <bits/hash_bytes.h> #endif diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index 9121934..11da4a7 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -31,7 +31,7 @@ // Level 2: C++ ABI #include <typeinfo> -#include <exception> +#include <bits/exception.h> #include <cstddef> #include "unwind.h" #include <bits/atomic_word.h> @@ -62,7 +62,7 @@ namespace __cxxabiv1 struct __cxa_exception { // Manage the exception object itself. - std::type_info *exceptionType; + const std::type_info *exceptionType; void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *); // The C++ standard has entertaining rules wrt calling set_terminate -- Gleb.