From nobody Tue Oct 29 22:17:49 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XdPlL2PVmz5c1sr; Tue, 29 Oct 2024 22:17:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XdPlL1ql7z59HH; Tue, 29 Oct 2024 22:17:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730240270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vwrwUpKYNhYBb9DaT1m/fF+jBfLqOiYP37iFRgQ6cNM=; b=SH26M9x88ub+bKcPFbeAc8jMvzVTI4dOUMnLbMz2sWm5gjECQGNXhpsxwlbnaR+CGtJRMx BZLWM95Ix7uAQ7ArVHrXl0emz5RWMtnCCqH3x2YUHx6axDpH50Tp7FcVKAGPwV/mzmL8PA cRNeglEdqupuzj/JC3L90g8OQHQ1VZ+fHogzFUQHqg+HlKzu90TzcVdyBLhONxoRvlncek iMB5CmIV4JSmWcHKVZJ3QjWbJ8UIe3W1OKx2fzEfXZ9/k8md5Jp5/8BwHv5QaGA5KtlB2k AMTEkeoTAal8wG+RNcpma/73jOrA5ukxPC7yBF6ooWPpyCCevQSD3ELIZe2uhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1730240270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vwrwUpKYNhYBb9DaT1m/fF+jBfLqOiYP37iFRgQ6cNM=; b=LBJOb2QYTtG8PcY6HI/wRq4tSz96XULbMq+dFM1l2kN2ilCeDS91vgIU1vrO08MJNxp7bH Yz9whZzLy0wrRe+4mBfzB2GFQRUZpZOxdIjODleIQxLHIhM8MAUEJZg81phuQWQggV5X2i 4kgQYbzLdNH3Ql4BScdsnruLH+XitaEh8WPzy6bSdQ1LjsQbM5Ea9zuhAGQyMCx5DpetFO PLOgrErKc3Yr1k7xcHAnnybQBgOwMrgavNe5lXNnXMYx5wj28tcVdm7bK25aiZ3YangOAU HeXSQCQVwkwsKi/nkTkm0NUMnJyz3z0Licym1FABFLXlEqPOPoAYMTni0leN1g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1730240270; a=rsa-sha256; cv=none; b=m8L0TvrbeIZ+NOEpF6PzbAM7n1w1/d6JriIMC9QjqKaTDZgXYjmeMaMJByLcYn+iycs14u SCkUXjDkiwP1fsjMTP446nvjfEgI9065wqul+MJldw2m+qd+ZX5rSsE35t3K6SgtCtUKAZ uwPYfvdWNUMJriAryovWe5eiHo/TwgW4Up5VDcdtbh46HvZ5elwEuH8PH52fkXSx0qAZsL 0YZkr8/MqPZQ5pePoA5pABk0RXMX5bwlQ3mjKYMuNLUYk7CiiSCv5EUKU4wXXwjN1kZiD+ uO/bhcXOIaJ0DwrFdErmWOqS+IsGz2r/i+3zXZdLrSKArWSqcqXx9a7BM8mSTA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XdPlL0jygzhKD; Tue, 29 Oct 2024 22:17:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 49TMHo7g009618; Tue, 29 Oct 2024 22:17:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49TMHnKF009615; Tue, 29 Oct 2024 22:17:49 GMT (envelope-from git) Date: Tue, 29 Oct 2024 22:17:49 GMT Message-Id: <202410292217.49TMHnKF009615@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 17a7ea7e3e39 - stable/14 - libcxxrt: Update to upstream 698997bfde1f List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 17a7ea7e3e39cdfb1b367b27c7b38fb0ea6c0806 Auto-Submitted: auto-generated The branch stable/14 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=17a7ea7e3e39cdfb1b367b27c7b38fb0ea6c0806 commit 17a7ea7e3e39cdfb1b367b27c7b38fb0ea6c0806 Author: Ed Maste AuthorDate: 2024-10-22 23:40:09 +0000 Commit: Ed Maste CommitDate: 2024-10-29 22:17:05 +0000 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) --- contrib/libcxxrt/atomic.h | 2 +- contrib/libcxxrt/cxxabi.h | 17 +++- contrib/libcxxrt/exception.cc | 174 ++++++++++++++++++----------------- contrib/libcxxrt/libelftc_dem_gnu3.c | 92 +++++++++--------- contrib/libcxxrt/memory.cc | 14 ++- contrib/libcxxrt/noexception.cc | 4 +- contrib/libcxxrt/stdexcept.cc | 40 ++++---- contrib/libcxxrt/stdexcept.h | 42 +++++---- 8 files changed, 196 insertions(+), 189 deletions(-) diff --git a/contrib/libcxxrt/atomic.h b/contrib/libcxxrt/atomic.h index 701d05337cf1..0768c08038df 100644 --- a/contrib/libcxxrt/atomic.h +++ b/contrib/libcxxrt/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/contrib/libcxxrt/cxxabi.h b/contrib/libcxxrt/cxxabi.h index ef4076a08a0a..2bf7f99b5245 100644 --- a/contrib/libcxxrt/cxxabi.h +++ b/contrib/libcxxrt/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) 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 diff --git a/contrib/libcxxrt/exception.cc b/contrib/libcxxrt/exception.cc index b56333e979a2..c87fe5ac4468 100644 --- a/contrib/libcxxrt/exception.cc +++ b/contrib/libcxxrt/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) 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 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(__cxa_current_exception_type), &myinfo); + void *ip = reinterpret_cast(_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(ex)); + ex = realExceptionFromException(ex); + static const __class_type_info *e_ti = + static_cast(&typeid(std::exception)); + const __class_type_info *throw_ti = + dynamic_cast(ex->exceptionType); + if (throw_ti) + { + std::exception *e = + static_cast(e_ti->cast_to(static_cast(ex+1), throw_ti)); + if (e) + { + fprintf(stderr, " '%s'", e->what()); + } + } + + size_t bufferSize = 128; + char *demangled = static_cast(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 terminateHandler = abort; +static atomic terminateHandler = terminate_with_diagnostics; +#endif + /** The global unexpected exception handler. */ static atomic 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(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(__cxa_current_exception_type), &myinfo); - void *ip = reinterpret_cast(_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(thrown_exception)); - thrown_exception = realExceptionFromException(thrown_exception); - static const __class_type_info *e_ti = - static_cast(&typeid(std::exception)); - const __class_type_info *throw_ti = - dynamic_cast(thrown_exception->exceptionType); - if (throw_ti) - { - std::exception *e = - static_cast(e_ti->cast_to(static_cast(thrown_exception+1), - throw_ti)); - if (e) - { - fprintf(stderr, " '%s'", e->what()); - } - } - - size_t bufferSize = 128; - char *demangled = static_cast(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) diff --git a/contrib/libcxxrt/libelftc_dem_gnu3.c b/contrib/libcxxrt/libelftc_dem_gnu3.c index e75d1694562e..36e98deb1d2f 100644 --- a/contrib/libcxxrt/libelftc_dem_gnu3.c +++ b/contrib/libcxxrt/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; @@ -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 > */ + /* std::basic_iostream> */ if (!DEM_PUSH_STR(ddata, "std::basic_iostream >")) + "std::char_traits>")) return (0); ddata->last_sname = "basic_iostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_iostream >")); + ">")); return (1); case SIMPLE_HASH('S', 'i'): - /* std::basic_istream > */ + /* std::basic_istream> */ if (!DEM_PUSH_STR(ddata, "std::basic_istream >")) + "std::char_traits>")) return (0); ddata->last_sname = "basic_istream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_istream >")); + ">")); return (1); case SIMPLE_HASH('S', 'o'): - /* std::basic_ostream > */ + /* std::basic_ostream> */ if (!DEM_PUSH_STR(ddata, "std::basic_ostream >")) + "std::char_traits>")) return (0); ddata->last_sname = "basic_ostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_ostream >")); + ">")); return (1); case SIMPLE_HASH('S', 's'): /* - * std::basic_string, - * std::allocator > - * - * a.k.a std::string + * std::string for consistency with libcxxabi */ - if (!DEM_PUSH_STR(ddata, "std::basic_string, std::allocator >")) - 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," - " std::allocator >")); - 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/contrib/libcxxrt/memory.cc b/contrib/libcxxrt/memory.cc index 7beb048ae914..0702f63f4527 100644 --- a/contrib/libcxxrt/memory.cc +++ b/contrib/libcxxrt/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/contrib/libcxxrt/noexception.cc b/contrib/libcxxrt/noexception.cc index 25dac1279684..7d17920c7cf4 100644 --- a/contrib/libcxxrt/noexception.cc +++ b/contrib/libcxxrt/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/contrib/libcxxrt/stdexcept.cc b/contrib/libcxxrt/stdexcept.cc index c1cea39f6aa6..22c6930dca6b 100644 --- a/contrib/libcxxrt/stdexcept.cc +++ b/contrib/libcxxrt/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/contrib/libcxxrt/stdexcept.h b/contrib/libcxxrt/stdexcept.h index 892039357595..38cd36d8e566 100644 --- a/contrib/libcxxrt/stdexcept.h +++ b/contrib/libcxxrt/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; };