diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-05-05 22:09:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-05-05 22:09:43 +0000 |
commit | 68c772440bea6b8080326b60b8208dbfdfd491ee (patch) | |
tree | 8dcdeb310eaa7c6deca0725cd51fae935755af69 | |
parent | 17a515e2228cbf097267b0d4ceabd64c1ae7ddb4 (diff) |
Notes
-rw-r--r-- | exception.cc | 29 | ||||
-rw-r--r-- | memory.cc | 30 |
2 files changed, 37 insertions, 22 deletions
diff --git a/exception.cc b/exception.cc index 7781ebbebb9f..f94e95e74b0a 100644 --- a/exception.cc +++ b/exception.cc @@ -304,13 +304,17 @@ static pthread_key_t eh_key; static void exception_cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { - __cxa_free_exception(static_cast<void*>(ex)); + // Exception layout: + // [__cxa_exception [_Unwind_Exception]] [exception object] + // + // __cxa_free_exception expects a pointer to the exception object + __cxa_free_exception(static_cast<void*>(ex + 1)); } static void dependent_exception_cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { - __cxa_free_dependent_exception(static_cast<void*>(ex)); + __cxa_free_dependent_exception(static_cast<void*>(ex + 1)); } /** @@ -340,7 +344,8 @@ static void thread_cleanup(void* thread_info) if (info->foreign_exception_state != __cxa_thread_info::none) { _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions); - e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); + if (e->exception_cleanup) + e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); } else { @@ -516,7 +521,7 @@ static void emergency_malloc_free(char *ptr) break; } } - assert(buffer > 0 && + assert(buffer >= 0 && "Trying to free something that is not an emergency buffer!"); // emergency_malloc() is expected to return 0-initialized data. We don't // zero the buffer when allocating it, because the static buffers will @@ -556,7 +561,7 @@ static void free_exception(char *e) { // If this allocation is within the address range of the emergency buffer, // don't call free() because it was not allocated with malloc() - if ((e > emergency_buffer) && + if ((e >= emergency_buffer) && (e < (emergency_buffer + sizeof(emergency_buffer)))) { emergency_malloc_free(e); @@ -1280,12 +1285,13 @@ extern "C" void __cxa_end_catch() if (ti->foreign_exception_state != __cxa_thread_info::none) { - globals->caughtExceptions = 0; if (ti->foreign_exception_state != __cxa_thread_info::rethrown) { _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions); - e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); + if (e->exception_cleanup) + e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); } + globals->caughtExceptions = 0; ti->foreign_exception_state = __cxa_thread_info::none; return; } @@ -1472,6 +1478,15 @@ namespace std return info->globals.uncaughtExceptions != 0; } /** + * Returns the number of exceptions currently being thrown that have not + * been caught. This can occur inside a nested catch statement. + */ + int uncaught_exceptions() throw() + { + __cxa_thread_info *info = thread_info(); + return info->globals.uncaughtExceptions; + } + /** * Returns the current unexpected handler. */ unexpected_handler get_unexpected() throw() diff --git a/memory.cc b/memory.cc index c8d28fc87e5a..9fa9d2a7aec5 100644 --- a/memory.cc +++ b/memory.cc @@ -71,8 +71,17 @@ namespace std } +#if __cplusplus < 201103L +#define NOEXCEPT throw() +#define BADALLOC throw(std::bad_alloc) +#else +#define NOEXCEPT noexcept +#define BADALLOC +#endif + + __attribute__((weak)) -void* operator new(size_t size) +void* operator new(size_t size) BADALLOC { if (0 == size) { @@ -97,7 +106,7 @@ void* operator new(size_t size) } __attribute__((weak)) -void* operator new(size_t size, const std::nothrow_t &) throw() +void* operator new(size_t size, const std::nothrow_t &) NOEXCEPT { try { return :: operator new(size); @@ -110,27 +119,21 @@ void* operator new(size_t size, const std::nothrow_t &) throw() __attribute__((weak)) -void operator delete(void * ptr) -#if __cplusplus < 201000L -throw() -#endif +void operator delete(void * ptr) NOEXCEPT { free(ptr); } __attribute__((weak)) -void * operator new[](size_t size) -#if __cplusplus < 201000L -throw(std::bad_alloc) -#endif +void * operator new[](size_t size) BADALLOC { return ::operator new(size); } __attribute__((weak)) -void * operator new[](size_t size, const std::nothrow_t &) throw() +void * operator new[](size_t size, const std::nothrow_t &) NOEXCEPT { try { return ::operator new[](size); @@ -143,10 +146,7 @@ void * operator new[](size_t size, const std::nothrow_t &) throw() __attribute__((weak)) -void operator delete[](void * ptr) -#if __cplusplus < 201000L -throw() -#endif +void operator delete[](void * ptr) NOEXCEPT { ::operator delete(ptr); } |