aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2024-10-22 14:42:59 +0000
committerEd Maste <emaste@FreeBSD.org>2024-10-22 14:43:39 +0000
commit5a07cb04925d79523b5cf1cb11edfbc74b828af7 (patch)
treef6ee1482e4b70a1d1bfefb2ab3ffa81146aa70dc
parent156745f575946b366c430fc2bc7b9a90d5925b29 (diff)
Import libcxxrt master 698997bfde1fc81b0bc0bfd1a1e5e3ad6f33b634vendor/libcxxrt/2024-10-22-698997bfde1fc81b0bc0bfd1a1e5e3ad6f33b634
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
-rw-r--r--atomic.h2
-rw-r--r--cxxabi.h17
-rw-r--r--exception.cc183
-rw-r--r--libelftc_dem_gnu3.c94
-rw-r--r--memory.cc14
-rw-r--r--noexception.cc4
-rw-r--r--stdexcept.cc40
-rw-r--r--stdexcept.h42
8 files changed, 209 insertions, 187 deletions
diff --git a/atomic.h b/atomic.h
index 701d05337cf1..0768c08038df 100644
--- a/atomic.h
+++ b/atomic.h
@@ -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.
diff --git a/cxxabi.h b/cxxabi.h
index e021f85c905a..2bf7f99b5245 100644
--- a/cxxabi.h
+++ b/cxxabi.h
@@ -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);
+void *__cxa_allocate_exception(size_t thrown_size) _LIBCXXRT_NOEXCEPT;
-void __cxa_free_exception(void* thrown_exception);
+void __cxa_free_exception(void* thrown_exception) _LIBCXXRT_NOEXCEPT;
__cxa_exception *__cxa_init_primary_exception(
- void *object, std::type_info* tinfo, void (*dest)(void *));
+ void *object, std::type_info* tinfo, void (*dest)(void *)) _LIBCXXRT_NOEXCEPT;
/**
* Throws an exception returned by __cxa_current_primary_exception(). This
diff --git a/exception.cc b/exception.cc
index 15f93aeb23dc..c87fe5ac4468 100644
--- a/exception.cc
+++ b/exception.cc
@@ -121,7 +121,7 @@ static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex
}
-extern "C" void __cxa_free_exception(void *thrown_exception);
+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 = abort;
+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)
+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)
+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
@@ -681,38 +746,14 @@ void __cxa_free_dependent_exception(void *thrown_exception)
}
/**
- * 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,39 +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
- _Unwind_Backtrace(trace, 0);
-
- // Just abort. No need to call std::terminate for the second time
- abort();
break;
}
std::terminate();
@@ -792,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 *)) {
+ void *object, std::type_info* tinfo, void (*dest)(void *)) _LIBCXXRT_NOEXCEPT {
__cxa_exception *ex = reinterpret_cast<__cxa_exception*>(object) - 1;
ex->referenceCount = 0;
@@ -1243,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
@@ -1432,6 +1440,19 @@ extern "C" void __cxa_call_unexpected(void*exception)
}
/**
+ * ABI function, called when an object destructor exits due to an
+ * exception during stack unwinding.
+ *
+ * This function does not return.
+ */
+extern "C" void __cxa_call_terminate(void*exception) _LIBCXXRT_NOEXCEPT
+{
+ std::terminate();
+ // Should not be reached.
+ abort();
+}
+
+/**
* ABI function, returns the adjusted pointer to the exception object.
*/
extern "C" void *__cxa_get_exception_ptr(void *exceptionObject)
@@ -1452,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;
@@ -1469,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;
@@ -1484,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); }
@@ -1493,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); }
@@ -1503,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)
@@ -1536,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;
@@ -1545,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;
@@ -1553,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)
@@ -1565,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)
diff --git a/libelftc_dem_gnu3.c b/libelftc_dem_gnu3.c
index e75d1694562e..7e03385e2d16 100644
--- a/libelftc_dem_gnu3.c
+++ b/libelftc_dem_gnu3.c
@@ -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;
@@ -306,6 +299,21 @@ vector_str_pop(struct vector_str *v)
}
/**
+ * @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);
}
@@ -2472,7 +2476,7 @@ cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
assert(ddata->cur_output->size > 0);
if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)
ddata->last_sname =
- ddata->cur_output->container[ddata->output.size - 1];
+ ddata->cur_output->container[ddata->cur_output->size - 1];
ddata->cur += len;
@@ -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;
diff --git a/memory.cc b/memory.cc
index 7beb048ae914..0702f63f4527 100644
--- a/memory.cc
+++ b/memory.cc
@@ -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);
}
diff --git a/noexception.cc b/noexception.cc
index 25dac1279684..7d17920c7cf4 100644
--- a/noexception.cc
+++ b/noexception.cc
@@ -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;
}
diff --git a/stdexcept.cc b/stdexcept.cc
index c1cea39f6aa6..22c6930dca6b 100644
--- a/stdexcept.cc
+++ b/stdexcept.cc
@@ -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";
}
diff --git a/stdexcept.h b/stdexcept.h
index 892039357595..38cd36d8e566 100644
--- a/stdexcept.h
+++ b/stdexcept.h
@@ -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;
};