libcxxrt: Update to upstream 698997bfde1f

Interesting fixes:

045c52c Mark __cxa_allocate_exception, __cxa_free_exception and
        __cxa_init_primary_exception noexcept.
8a2f123 Define _LIBCXXRT_NOEXCEPT in cxxabi.h and use it instead of
        throw()
9529236 Fix memory corruption in cpp_demangle_read_sname()
8f5c74e Add test cases, fix more bugs, and improve perf
391a3dc Add a simple implementation of __cxa_call_terminate
40e4fa2 mark std::terminate as noreturn and noexcept
5eede09 Print diagnostics in default std::terminate handler

Reviewed by:	dim
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D47238

(cherry picked from commit 13da1af1cd677b7901d3bf4b9dbe3290b94130d5)
This commit is contained in:
Ed Maste 2024-10-22 19:40:09 -04:00
parent b426202aaf
commit 17a7ea7e3e
8 changed files with 197 additions and 190 deletions

View file

@ -56,7 +56,7 @@ namespace
/**
* Constructor, takes a value.
*/
atomic(T init) : val(init) {}
constexpr atomic(T init) : val(init) {}
/**
* Atomically load with the specified memory order.

View file

@ -41,8 +41,15 @@ namespace std
*/
#ifdef __cplusplus
#if __cplusplus < 201103L
#define _LIBCXXRT_NOEXCEPT throw()
#else
#define _LIBCXXRT_NOEXCEPT noexcept
#endif
namespace __cxxabiv1 {
extern "C" {
#else
#define _LIBCXXRT_NOEXCEPT
#endif
/**
* Function type to call when an unexpected exception is encountered.
@ -76,7 +83,7 @@ typedef void (*terminate_handler)();
*/
struct __cxa_exception
{
#if __LP64__
#ifdef __LP64__
/**
* Now _Unwind_Exception is marked with __attribute__((aligned)), which
* implies __cxa_exception is also aligned. Insert padding in the
@ -154,7 +161,7 @@ struct __cxa_exception
* need to adjust the thrown pointer to make it all work correctly.
*/
void *adjustedPtr;
#if !__LP64__
#ifndef __LP64__
/**
* Reference count. Used to support the C++11 exception_ptr class. This
* is prepended to the structure in 64-bit mode and squeezed in to the
@ -204,12 +211,12 @@ __cxa_eh_globals *__cxa_get_globals_fast(void);
std::type_info * __cxa_current_exception_type();
void *__cxa_allocate_exception(size_t thrown_size) throw();
void *__cxa_allocate_exception(size_t thrown_size) _LIBCXXRT_NOEXCEPT;
void __cxa_free_exception(void* thrown_exception) throw();
void __cxa_free_exception(void* thrown_exception) _LIBCXXRT_NOEXCEPT;
__cxa_exception *__cxa_init_primary_exception(
void *object, std::type_info* tinfo, void (*dest)(void *)) throw();
void *object, std::type_info* tinfo, void (*dest)(void *)) _LIBCXXRT_NOEXCEPT;
/**
* Throws an exception returned by __cxa_current_primary_exception(). This

View file

@ -121,7 +121,7 @@ static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex
}
extern "C" void __cxa_free_exception(void *thrown_exception) throw();
extern "C" void __cxa_free_exception(void *thrown_exception) _LIBCXXRT_NOEXCEPT;
extern "C" void __cxa_free_dependent_exception(void *thrown_exception);
extern "C" void* __dynamic_cast(const void *sub,
const __class_type_info *src,
@ -198,7 +198,7 @@ struct __cxa_thread_info
*/
struct __cxa_dependent_exception
{
#if __LP64__
#ifdef __LP64__
void *reserve;
void *primaryException;
#endif
@ -217,7 +217,7 @@ struct __cxa_dependent_exception
const char *languageSpecificData;
void *catchTemp;
void *adjustedPtr;
#if !__LP64__
#ifndef __LP64__
void *primaryException;
#endif
_Unwind_Exception unwindHeader;
@ -241,8 +241,8 @@ namespace std
class exception
{
public:
virtual ~exception() throw();
virtual const char* what() const throw();
virtual ~exception() _LIBCXXRT_NOEXCEPT;
virtual const char* what() const _LIBCXXRT_NOEXCEPT;
};
}
@ -296,15 +296,80 @@ namespace std
{
// Forward declaration of standard library terminate() function used to
// abort execution.
void terminate(void);
[[noreturn]] void terminate(void) _LIBCXXRT_NOEXCEPT;
}
using namespace ABI_NAMESPACE;
#ifdef LIBCXXRT_NO_DEFAULT_TERMINATE_DIAGNOSTICS
/** The global termination handler. */
static atomic<terminate_handler> terminateHandler = abort;
#else
/**
* Callback function used with _Unwind_Backtrace().
*
* Prints a stack trace. Used only for debugging help.
*
* Note: As of FreeBSD 8.1, dladdr() still doesn't work properly, so this only
* correctly prints function names from public, relocatable, symbols.
*/
static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
{
Dl_info myinfo;
int mylookup =
dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo);
void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context));
Dl_info info;
if (dladdr(ip, &info) != 0)
{
if (mylookup == 0 || strcmp(info.dli_fname, myinfo.dli_fname) != 0)
{
printf("%p:%s() in %s\n", ip, info.dli_sname, info.dli_fname);
}
}
return _URC_CONTINUE_UNWIND;
}
static void terminate_with_diagnostics() {
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *ex = globals->caughtExceptions;
if (ex != nullptr) {
fprintf(stderr, "Terminating due to uncaught exception %p", static_cast<void*>(ex));
ex = realExceptionFromException(ex);
static const __class_type_info *e_ti =
static_cast<const __class_type_info*>(&typeid(std::exception));
const __class_type_info *throw_ti =
dynamic_cast<const __class_type_info*>(ex->exceptionType);
if (throw_ti)
{
std::exception *e =
static_cast<std::exception*>(e_ti->cast_to(static_cast<void*>(ex+1), throw_ti));
if (e)
{
fprintf(stderr, " '%s'", e->what());
}
}
size_t bufferSize = 128;
char *demangled = static_cast<char*>(malloc(bufferSize));
const char *mangled = ex->exceptionType->name();
int status;
demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
fprintf(stderr, " of type %s\n",
status == 0 ? demangled : mangled);
if (status == 0) { free(demangled); }
_Unwind_Backtrace(trace, 0);
}
abort();
}
/** The global termination handler. */
static atomic<terminate_handler> terminateHandler = terminate_with_diagnostics;
#endif
/** The global unexpected exception handler. */
static atomic<unexpected_handler> unexpectedHandler = std::terminate;
@ -611,7 +676,7 @@ static void free_exception(char *e)
* emergency buffer if malloc() fails, and may block if there are no such
* buffers available.
*/
extern "C" void *__cxa_allocate_exception(size_t thrown_size) throw()
extern "C" void *__cxa_allocate_exception(size_t thrown_size) _LIBCXXRT_NOEXCEPT
{
size_t size = thrown_size + sizeof(__cxa_exception);
char *buffer = alloc_or_die(size);
@ -633,7 +698,7 @@ extern "C" void *__cxa_allocate_dependent_exception(void)
* In this implementation, it is also called by __cxa_end_catch() and during
* thread cleanup.
*/
extern "C" void __cxa_free_exception(void *thrown_exception) throw()
extern "C" void __cxa_free_exception(void *thrown_exception) _LIBCXXRT_NOEXCEPT
{
__cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1;
// Free the object that was thrown, calling its destructor
@ -680,39 +745,15 @@ void __cxa_free_dependent_exception(void *thrown_exception)
free_exception(reinterpret_cast<char*>(ex));
}
/**
* Callback function used with _Unwind_Backtrace().
*
* Prints a stack trace. Used only for debugging help.
*
* Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only
* correctly prints function names from public, relocatable, symbols.
*/
static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
{
Dl_info myinfo;
int mylookup =
dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo);
void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context));
Dl_info info;
if (dladdr(ip, &info) != 0)
{
if (mylookup == 0 || strcmp(info.dli_fname, myinfo.dli_fname) != 0)
{
printf("%p:%s() in %s\n", ip, info.dli_sname, info.dli_fname);
}
}
return _URC_CONTINUE_UNWIND;
}
/**
* Report a failure that occurred when attempting to throw an exception.
*
* If the failure happened by falling off the end of the stack without finding
* a handler, prints a back trace before aborting.
* a handler, catch the exception before calling terminate. The default
* terminate handler will print a backtrace before aborting.
*/
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
extern "C" void *__cxa_begin_catch(void *e) throw();
extern "C" void *__cxa_begin_catch(void *e) _LIBCXXRT_NOEXCEPT;
#else
extern "C" void *__cxa_begin_catch(void *e);
#endif
@ -731,41 +772,6 @@ static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exce
#endif
case _URC_END_OF_STACK:
__cxa_begin_catch (&(thrown_exception->unwindHeader));
std::terminate();
fprintf(stderr, "Terminating due to uncaught exception %p",
static_cast<void*>(thrown_exception));
thrown_exception = realExceptionFromException(thrown_exception);
static const __class_type_info *e_ti =
static_cast<const __class_type_info*>(&typeid(std::exception));
const __class_type_info *throw_ti =
dynamic_cast<const __class_type_info*>(thrown_exception->exceptionType);
if (throw_ti)
{
std::exception *e =
static_cast<std::exception*>(e_ti->cast_to(static_cast<void*>(thrown_exception+1),
throw_ti));
if (e)
{
fprintf(stderr, " '%s'", e->what());
}
}
size_t bufferSize = 128;
char *demangled = static_cast<char*>(malloc(bufferSize));
const char *mangled = thrown_exception->exceptionType->name();
int status;
demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
fprintf(stderr, " of type %s\n",
status == 0 ? demangled : mangled);
if (status == 0) { free(demangled); }
// Print a back trace if no handler is found.
// TODO: Make this optional
#ifndef __arm__
_Unwind_Backtrace(trace, 0);
#endif
// Just abort. No need to call std::terminate for the second time
abort();
break;
}
std::terminate();
@ -794,7 +800,7 @@ static void throw_exception(__cxa_exception *ex)
}
extern "C" __cxa_exception *__cxa_init_primary_exception(
void *object, std::type_info* tinfo, void (*dest)(void *)) throw() {
void *object, std::type_info* tinfo, void (*dest)(void *)) _LIBCXXRT_NOEXCEPT {
__cxa_exception *ex = reinterpret_cast<__cxa_exception*>(object) - 1;
ex->referenceCount = 0;
@ -1245,7 +1251,7 @@ BEGIN_PERSONALITY_FUNCTION(__gxx_personality_v0)
* C++ exceptions) of the unadjusted pointer (for foreign exceptions).
*/
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
extern "C" void *__cxa_begin_catch(void *e) throw()
extern "C" void *__cxa_begin_catch(void *e) _LIBCXXRT_NOEXCEPT
#else
extern "C" void *__cxa_begin_catch(void *e)
#endif
@ -1439,7 +1445,7 @@ extern "C" void __cxa_call_unexpected(void*exception)
*
* This function does not return.
*/
extern "C" void __cxa_call_terminate(void *exception) throw()
extern "C" void __cxa_call_terminate(void*exception) _LIBCXXRT_NOEXCEPT
{
std::terminate();
// Should not be reached.
@ -1467,14 +1473,14 @@ namespace pathscale
/**
* Sets whether unexpected and terminate handlers should be thread-local.
*/
void set_use_thread_local_handlers(bool flag) throw()
void set_use_thread_local_handlers(bool flag) _LIBCXXRT_NOEXCEPT
{
thread_local_handlers = flag;
}
/**
* Sets a thread-local unexpected handler.
*/
unexpected_handler set_unexpected(unexpected_handler f) throw()
unexpected_handler set_unexpected(unexpected_handler f) _LIBCXXRT_NOEXCEPT
{
static __cxa_thread_info *info = thread_info();
unexpected_handler old = info->unexpectedHandler;
@ -1484,7 +1490,7 @@ namespace pathscale
/**
* Sets a thread-local terminate handler.
*/
terminate_handler set_terminate(terminate_handler f) throw()
terminate_handler set_terminate(terminate_handler f) _LIBCXXRT_NOEXCEPT
{
static __cxa_thread_info *info = thread_info();
terminate_handler old = info->terminateHandler;
@ -1499,7 +1505,7 @@ namespace std
* Sets the function that will be called when an exception specification is
* violated.
*/
unexpected_handler set_unexpected(unexpected_handler f) throw()
unexpected_handler set_unexpected(unexpected_handler f) _LIBCXXRT_NOEXCEPT
{
if (thread_local_handlers) { return pathscale::set_unexpected(f); }
@ -1508,7 +1514,7 @@ namespace std
/**
* Sets the function that is called to terminate the program.
*/
terminate_handler set_terminate(terminate_handler f) throw()
terminate_handler set_terminate(terminate_handler f) _LIBCXXRT_NOEXCEPT
{
if (thread_local_handlers) { return pathscale::set_terminate(f); }
@ -1518,7 +1524,7 @@ namespace std
* Terminates the program, calling a custom terminate implementation if
* required.
*/
void terminate()
[[noreturn]] void terminate() _LIBCXXRT_NOEXCEPT
{
static __cxa_thread_info *info = thread_info();
if (0 != info && 0 != info->terminateHandler)
@ -1551,7 +1557,7 @@ namespace std
* Returns whether there are any exceptions currently being thrown that
* have not been caught. This can occur inside a nested catch statement.
*/
bool uncaught_exception() throw()
bool uncaught_exception() _LIBCXXRT_NOEXCEPT
{
__cxa_thread_info *info = thread_info();
return info->globals.uncaughtExceptions != 0;
@ -1560,7 +1566,7 @@ namespace std
* 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()
int uncaught_exceptions() _LIBCXXRT_NOEXCEPT
{
__cxa_thread_info *info = thread_info();
return info->globals.uncaughtExceptions;
@ -1568,7 +1574,7 @@ namespace std
/**
* Returns the current unexpected handler.
*/
unexpected_handler get_unexpected() throw()
unexpected_handler get_unexpected() _LIBCXXRT_NOEXCEPT
{
__cxa_thread_info *info = thread_info();
if (info->unexpectedHandler)
@ -1580,7 +1586,7 @@ namespace std
/**
* Returns the current terminate handler.
*/
terminate_handler get_terminate() throw()
terminate_handler get_terminate() _LIBCXXRT_NOEXCEPT
{
__cxa_thread_info *info = thread_info();
if (info->terminateHandler)

View file

@ -200,9 +200,9 @@ vector_str_find(const struct vector_str *v, const char *o, size_t l)
static char *
vector_str_get_flat(const struct vector_str *v, size_t *l)
{
ssize_t elem_pos, elem_size, rtn_size;
size_t i;
char *rtn;
char *rtn, *p;
ssize_t rtn_size;
if (v == NULL || v->size == 0)
return (NULL);
@ -213,16 +213,9 @@ vector_str_get_flat(const struct vector_str *v, size_t *l)
if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL)
return (NULL);
elem_pos = 0;
for (i = 0; i < v->size; ++i) {
elem_size = strlen(v->container[i]);
memcpy(rtn + elem_pos, v->container[i], elem_size);
elem_pos += elem_size;
}
rtn[rtn_size] = '\0';
p = rtn;
for (i = 0; i < v->size; ++i)
p = stpcpy(p, v->container[i]);
if (l != NULL)
*l = rtn_size;
@ -305,6 +298,21 @@ vector_str_pop(struct vector_str *v)
return (true);
}
/**
* @brief Implements strlcpy() without result.
*/
static void
copy_string(char *dst, const char *src, size_t dsize)
{
size_t remain;
if ((remain = dsize))
while (--remain)
if (!(*dst++ = *src++))
break;
if (!remain && dsize)
*dst = 0;
}
/**
* @brief Push back string to vector.
* @return false at failed, true at success.
@ -322,7 +330,7 @@ vector_str_push(struct vector_str *v, const char *str, size_t len)
if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL)
return (false);
snprintf(v->container[v->size], len + 1, "%s", str);
copy_string(v->container[v->size], str, len + 1);
++v->size;
@ -420,8 +428,8 @@ static char *
vector_str_substr(const struct vector_str *v, size_t begin, size_t end,
size_t *r_len)
{
size_t cur, i, len;
char *rtn;
char *rtn, *p;
size_t i, len;
if (v == NULL || begin > end)
return (NULL);
@ -436,13 +444,9 @@ vector_str_substr(const struct vector_str *v, size_t begin, size_t end,
if (r_len != NULL)
*r_len = len;
cur = 0;
for (i = begin; i < end + 1; ++i) {
len = strlen(v->container[i]);
memcpy(rtn + cur, v->container[i], len);
cur += len;
}
rtn[cur] = '\0';
p = rtn;
for (i = begin; i < end + 1; ++i)
p = stpcpy(p, v->container[i]);
return (rtn);
}
@ -2510,61 +2514,56 @@ cpp_demangle_read_subst(struct cpp_demangle_data *ddata)
return (1);
case SIMPLE_HASH('S', 'd'):
/* std::basic_iostream<char, std::char_traits<char> > */
/* std::basic_iostream<char, std::char_traits<char>> */
if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, "
"std::char_traits<char> >"))
"std::char_traits<char>>"))
return (0);
ddata->last_sname = "basic_iostream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
"std::basic_iostream<char, std::char_traits"
"<char> >"));
"<char>>"));
return (1);
case SIMPLE_HASH('S', 'i'):
/* std::basic_istream<char, std::char_traits<char> > */
/* std::basic_istream<char, std::char_traits<char>> */
if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, "
"std::char_traits<char> >"))
"std::char_traits<char>>"))
return (0);
ddata->last_sname = "basic_istream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
"std::basic_istream<char, std::char_traits"
"<char> >"));
"<char>>"));
return (1);
case SIMPLE_HASH('S', 'o'):
/* std::basic_ostream<char, std::char_traits<char> > */
/* std::basic_ostream<char, std::char_traits<char>> */
if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, "
"std::char_traits<char> >"))
"std::char_traits<char>>"))
return (0);
ddata->last_sname = "basic_ostream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
"std::basic_ostream<char, std::char_traits"
"<char> >"));
"<char>>"));
return (1);
case SIMPLE_HASH('S', 's'):
/*
* std::basic_string<char, std::char_traits<char>,
* std::allocator<char> >
*
* a.k.a std::string
* std::string for consistency with libcxxabi
*/
if (!DEM_PUSH_STR(ddata, "std::basic_string<char, "
"std::char_traits<char>, std::allocator<char> >"))
return (0);
if (!DEM_PUSH_STR(ddata, "std::string"))
return 0;
ddata->last_sname = "string";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
"std::basic_string<char, std::char_traits<char>,"
" std::allocator<char> >"));
return (1);
return cpp_demangle_read_subst_stdtmpl(ddata,
"std::string");
return 1;
case SIMPLE_HASH('S', 't'):
/* std:: */
@ -2740,7 +2739,7 @@ static int
cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
{
struct vector_str *v;
size_t arg_len, idx, limit, size;
size_t arg_len, idx, limit;
char *arg;
if (ddata == NULL || *ddata->cur == '\0')
@ -2773,12 +2772,7 @@ cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
if (*ddata->cur == 'E') {
++ddata->cur;
size = v->size;
assert(size > 0);
if (!strncmp(v->container[size - 1], ">", 1)) {
if (!DEM_PUSH_STR(ddata, " >"))
return (0);
} else if (!DEM_PUSH_STR(ddata, ">"))
if (!DEM_PUSH_STR(ddata, ">"))
return (0);
ddata->is_tmpl = true;
break;

View file

@ -73,10 +73,8 @@ namespace std
#if __cplusplus < 201103L
#define NOEXCEPT throw()
#define BADALLOC throw(std::bad_alloc)
#else
#define NOEXCEPT noexcept
#define BADALLOC
#endif
@ -138,14 +136,14 @@ void* operator new(size_t size) BADALLOC
__attribute__((weak))
void* operator new(size_t size, const std::nothrow_t &) NOEXCEPT
void* operator new(size_t size, const std::nothrow_t &) _LIBCXXRT_NOEXCEPT
{
return noexcept_new<(::operator new)>(size);
}
__attribute__((weak))
void operator delete(void * ptr) NOEXCEPT
void operator delete(void * ptr) _LIBCXXRT_NOEXCEPT
{
free(ptr);
}
@ -159,14 +157,14 @@ void * operator new[](size_t size) BADALLOC
__attribute__((weak))
void * operator new[](size_t size, const std::nothrow_t &) NOEXCEPT
void * operator new[](size_t size, const std::nothrow_t &) _LIBCXXRT_NOEXCEPT
{
return noexcept_new<(::operator new[])>(size);
}
__attribute__((weak))
void operator delete[](void * ptr) NOEXCEPT
void operator delete[](void * ptr) _LIBCXXRT_NOEXCEPT
{
::operator delete(ptr);
}
@ -176,14 +174,14 @@ void operator delete[](void * ptr) NOEXCEPT
#if __cplusplus >= 201402L
__attribute__((weak))
void operator delete(void * ptr, size_t) NOEXCEPT
void operator delete(void * ptr, size_t) _LIBCXXRT_NOEXCEPT
{
::operator delete(ptr);
}
__attribute__((weak))
void operator delete[](void * ptr, size_t) NOEXCEPT
void operator delete[](void * ptr, size_t) _LIBCXXRT_NOEXCEPT
{
::operator delete(ptr);
}

View file

@ -30,7 +30,7 @@ namespace std
* Returns whether there are any exceptions currently being thrown that
* have not been caught. Without exception support this is always false.
*/
bool uncaught_exception() throw()
bool uncaught_exception() _LIBCXXRT_NOEXCEPT
{
return false;
}
@ -38,7 +38,7 @@ namespace std
* Returns the number of exceptions currently being thrown that have not
* been caught. Without exception support this is always 0.
*/
int uncaught_exceptions() throw()
int uncaught_exceptions() _LIBCXXRT_NOEXCEPT
{
return 0;
}

View file

@ -31,66 +31,66 @@
namespace std {
exception::exception() throw() {}
exception::exception() _LIBCXXRT_NOEXCEPT {}
exception::~exception() {}
exception::exception(const exception&) throw() {}
exception& exception::operator=(const exception&) throw()
exception::exception(const exception&) _LIBCXXRT_NOEXCEPT {}
exception& exception::operator=(const exception&) _LIBCXXRT_NOEXCEPT
{
return *this;
}
const char* exception::what() const throw()
const char* exception::what() const _LIBCXXRT_NOEXCEPT
{
return "std::exception";
}
bad_alloc::bad_alloc() throw() {}
bad_alloc::bad_alloc() _LIBCXXRT_NOEXCEPT {}
bad_alloc::~bad_alloc() {}
bad_alloc::bad_alloc(const bad_alloc&) throw() {}
bad_alloc& bad_alloc::operator=(const bad_alloc&) throw()
bad_alloc::bad_alloc(const bad_alloc&) _LIBCXXRT_NOEXCEPT {}
bad_alloc& bad_alloc::operator=(const bad_alloc&) _LIBCXXRT_NOEXCEPT
{
return *this;
}
const char* bad_alloc::what() const throw()
const char* bad_alloc::what() const _LIBCXXRT_NOEXCEPT
{
return "cxxrt::bad_alloc";
}
bad_cast::bad_cast() throw() {}
bad_cast::bad_cast() _LIBCXXRT_NOEXCEPT {}
bad_cast::~bad_cast() {}
bad_cast::bad_cast(const bad_cast&) throw() {}
bad_cast& bad_cast::operator=(const bad_cast&) throw()
bad_cast::bad_cast(const bad_cast&) _LIBCXXRT_NOEXCEPT {}
bad_cast& bad_cast::operator=(const bad_cast&) _LIBCXXRT_NOEXCEPT
{
return *this;
}
const char* bad_cast::what() const throw()
const char* bad_cast::what() const _LIBCXXRT_NOEXCEPT
{
return "std::bad_cast";
}
bad_typeid::bad_typeid() throw() {}
bad_typeid::bad_typeid() _LIBCXXRT_NOEXCEPT {}
bad_typeid::~bad_typeid() {}
bad_typeid::bad_typeid(const bad_typeid &__rhs) throw() {}
bad_typeid& bad_typeid::operator=(const bad_typeid &__rhs) throw()
bad_typeid::bad_typeid(const bad_typeid &__rhs) _LIBCXXRT_NOEXCEPT {}
bad_typeid& bad_typeid::operator=(const bad_typeid &__rhs) _LIBCXXRT_NOEXCEPT
{
return *this;
}
const char* bad_typeid::what() const throw()
const char* bad_typeid::what() const _LIBCXXRT_NOEXCEPT
{
return "std::bad_typeid";
}
bad_array_new_length::bad_array_new_length() throw() {}
bad_array_new_length::bad_array_new_length() _LIBCXXRT_NOEXCEPT {}
bad_array_new_length::~bad_array_new_length() {}
bad_array_new_length::bad_array_new_length(const bad_array_new_length&) throw() {}
bad_array_new_length& bad_array_new_length::operator=(const bad_array_new_length&) throw()
bad_array_new_length::bad_array_new_length(const bad_array_new_length&) _LIBCXXRT_NOEXCEPT {}
bad_array_new_length& bad_array_new_length::operator=(const bad_array_new_length&) _LIBCXXRT_NOEXCEPT
{
return *this;
}
const char* bad_array_new_length::what() const throw()
const char* bad_array_new_length::what() const _LIBCXXRT_NOEXCEPT
{
return "std::bad_array_new_length";
}

View file

@ -29,17 +29,19 @@
* of the exceptions for the runtime to use.
*/
#include "cxxabi.h"
namespace std
{
class exception
{
public:
exception() throw();
exception(const exception&) throw();
exception& operator=(const exception&) throw();
exception() _LIBCXXRT_NOEXCEPT;
exception(const exception&) _LIBCXXRT_NOEXCEPT;
exception& operator=(const exception&) _LIBCXXRT_NOEXCEPT;
virtual ~exception();
virtual const char* what() const throw();
virtual const char* what() const _LIBCXXRT_NOEXCEPT;
};
@ -49,11 +51,11 @@ namespace std
class bad_alloc: public exception
{
public:
bad_alloc() throw();
bad_alloc(const bad_alloc&) throw();
bad_alloc& operator=(const bad_alloc&) throw();
bad_alloc() _LIBCXXRT_NOEXCEPT;
bad_alloc(const bad_alloc&) _LIBCXXRT_NOEXCEPT;
bad_alloc& operator=(const bad_alloc&) _LIBCXXRT_NOEXCEPT;
~bad_alloc();
virtual const char* what() const throw();
virtual const char* what() const _LIBCXXRT_NOEXCEPT;
};
/**
@ -61,11 +63,11 @@ namespace std
*/
class bad_cast: public exception {
public:
bad_cast() throw();
bad_cast(const bad_cast&) throw();
bad_cast& operator=(const bad_cast&) throw();
bad_cast() _LIBCXXRT_NOEXCEPT;
bad_cast(const bad_cast&) _LIBCXXRT_NOEXCEPT;
bad_cast& operator=(const bad_cast&) _LIBCXXRT_NOEXCEPT;
virtual ~bad_cast();
virtual const char* what() const throw();
virtual const char* what() const _LIBCXXRT_NOEXCEPT;
};
/**
@ -74,21 +76,21 @@ namespace std
class bad_typeid: public exception
{
public:
bad_typeid() throw();
bad_typeid(const bad_typeid &__rhs) throw();
bad_typeid() _LIBCXXRT_NOEXCEPT;
bad_typeid(const bad_typeid &__rhs) _LIBCXXRT_NOEXCEPT;
virtual ~bad_typeid();
bad_typeid& operator=(const bad_typeid &__rhs) throw();
virtual const char* what() const throw();
bad_typeid& operator=(const bad_typeid &__rhs) _LIBCXXRT_NOEXCEPT;
virtual const char* what() const _LIBCXXRT_NOEXCEPT;
};
class bad_array_new_length: public bad_alloc
{
public:
bad_array_new_length() throw();
bad_array_new_length(const bad_array_new_length&) throw();
bad_array_new_length& operator=(const bad_array_new_length&) throw();
bad_array_new_length() _LIBCXXRT_NOEXCEPT;
bad_array_new_length(const bad_array_new_length&) _LIBCXXRT_NOEXCEPT;
bad_array_new_length& operator=(const bad_array_new_length&) _LIBCXXRT_NOEXCEPT;
virtual ~bad_array_new_length();
virtual const char *what() const throw();
virtual const char *what() const _LIBCXXRT_NOEXCEPT;
};