From 80212b03ff792ddfff82092b35aa7ed0fdf937a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 17 Jan 2026 05:25:15 +0100 Subject: [PATCH] libcxxabi: update to LLVM 22 --- lib/libcxxabi/include/__cxxabi_config.h | 65 +++++---- lib/libcxxabi/src/cxa_exception.cpp | 6 +- lib/libcxxabi/src/cxa_exception.h | 30 ++-- lib/libcxxabi/src/cxa_personality.cpp | 137 +++++++++++++++++-- lib/libcxxabi/src/cxa_thread_atexit.cpp | 3 +- lib/libcxxabi/src/demangle/DemangleConfig.h | 4 + lib/libcxxabi/src/demangle/ItaniumDemangle.h | 15 +- lib/libcxxabi/src/demangle/Utility.h | 28 +++- lib/libcxxabi/src/fallback_malloc.cpp | 2 +- lib/libcxxabi/src/private_typeinfo.cpp | 6 + lib/libcxxabi/src/stdlib_new_delete.cpp | 10 +- 11 files changed, 235 insertions(+), 71 deletions(-) diff --git a/lib/libcxxabi/include/__cxxabi_config.h b/lib/libcxxabi/include/__cxxabi_config.h index 759445dac9..e4fd845b1f 100644 --- a/lib/libcxxabi/include/__cxxabi_config.h +++ b/lib/libcxxabi/include/__cxxabi_config.h @@ -14,10 +14,6 @@ #define _LIBCXXABI_ARM_EHABI #endif -#if !defined(__has_attribute) -#define __has_attribute(_attribute_) 0 -#endif - #if defined(__clang__) # define _LIBCXXABI_COMPILER_CLANG # ifndef __apple_build_version__ @@ -25,10 +21,6 @@ # endif #elif defined(__GNUC__) # define _LIBCXXABI_COMPILER_GCC -#elif defined(_MSC_VER) -# define _LIBCXXABI_COMPILER_MSVC -#elif defined(__IBMCPP__) -# define _LIBCXXABI_COMPILER_IBM #endif #if defined(_WIN32) @@ -66,17 +58,7 @@ #endif #endif -#if defined(_LIBCXXABI_COMPILER_MSVC) -#define _LIBCXXABI_WEAK -#else #define _LIBCXXABI_WEAK __attribute__((__weak__)) -#endif - -#if defined(__clang__) -#define _LIBCXXABI_COMPILER_CLANG -#elif defined(__GNUC__) -#define _LIBCXXABI_COMPILER_GCC -#endif #if __has_attribute(__no_sanitize__) && defined(_LIBCXXABI_COMPILER_CLANG) #define _LIBCXXABI_NO_CFI __attribute__((__no_sanitize__("cfi"))) @@ -89,11 +71,7 @@ # define _LIBCXXABI_GUARD_ABI_ARM #endif -#if defined(_LIBCXXABI_COMPILER_CLANG) -# if !__has_feature(cxx_exceptions) -# define _LIBCXXABI_NO_EXCEPTIONS -# endif -#elif defined(_LIBCXXABI_COMPILER_GCC) && !defined(__EXCEPTIONS) +#if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L # define _LIBCXXABI_NO_EXCEPTIONS #endif @@ -103,6 +81,47 @@ #define _LIBCXXABI_DTOR_FUNC #endif +#if __has_include() +# include +#endif + +#if __has_feature(ptrauth_calls) + +// ptrauth_string_discriminator("__cxa_exception::actionRecord") == 0xFC91 +# define __ptrauth_cxxabi_action_record __ptrauth(ptrauth_key_process_dependent_data, 1, 0xFC91) + +// ptrauth_string_discriminator("__cxa_exception::languageSpecificData") == 0xE8EE +# define __ptrauth_cxxabi_lsd __ptrauth(ptrauth_key_process_dependent_data, 1, 0xE8EE) + +// ptrauth_string_discriminator("__cxa_exception::catchTemp") == 0xFA58 +# define __ptrauth_cxxabi_catch_temp_disc 0xFA58 +# define __ptrauth_cxxabi_catch_temp_key ptrauth_key_process_dependent_data +# define __ptrauth_cxxabi_catch_temp __ptrauth(__ptrauth_cxxabi_catch_temp_key, 1, __ptrauth_cxxabi_catch_temp_disc) + +// ptrauth_string_discriminator("__cxa_exception::adjustedPtr") == 0x99E4 +# define __ptrauth_cxxabi_adjusted_ptr __ptrauth(ptrauth_key_process_dependent_data, 1, 0x99E4) + +// ptrauth_string_discriminator("__cxa_exception::unexpectedHandler") == 0x99A9 +# define __ptrauth_cxxabi_unexpected_handler __ptrauth(ptrauth_key_function_pointer, 1, 0x99A9) + +// ptrauth_string_discriminator("__cxa_exception::terminateHandler") == 0x0886) +# define __ptrauth_cxxabi_terminate_handler __ptrauth(ptrauth_key_function_pointer, 1, 0x886) + +// ptrauth_string_discriminator("__cxa_exception::exceptionDestructor") == 0xC088 +# define __ptrauth_cxxabi_exception_destructor __ptrauth(ptrauth_key_function_pointer, 1, 0xC088) + +#else + +# define __ptrauth_cxxabi_action_record +# define __ptrauth_cxxabi_lsd +# define __ptrauth_cxxabi_catch_temp +# define __ptrauth_cxxabi_adjusted_ptr +# define __ptrauth_cxxabi_unexpected_handler +# define __ptrauth_cxxabi_terminate_handler +# define __ptrauth_cxxabi_exception_destructor + +#endif + #if __cplusplus < 201103L # define _LIBCXXABI_NOEXCEPT throw() #else diff --git a/lib/libcxxabi/src/cxa_exception.cpp b/lib/libcxxabi/src/cxa_exception.cpp index 92901a83bf..5d7edae697 100644 --- a/lib/libcxxabi/src/cxa_exception.cpp +++ b/lib/libcxxabi/src/cxa_exception.cpp @@ -192,7 +192,9 @@ void *__cxa_allocate_exception(size_t thrown_size) throw() { std::terminate(); __cxa_exception *exception_header = static_cast<__cxa_exception *>((void *)(raw_buffer + header_offset)); - ::memset(exception_header, 0, actual_size); + // We warn on memset to a non-trivially castable type. We might want to + // change that diagnostic to not fire on a trivially obvious zero fill. + ::memset(static_cast(exception_header), 0, actual_size); return thrown_object_from_cxa_exception(exception_header); } @@ -226,7 +228,7 @@ __cxa_exception* __cxa_init_primary_exception(void* object, std::type_info* tinf } // This function shall allocate a __cxa_dependent_exception and -// return a pointer to it. (Really to the object, not past its' end). +// return a pointer to it. (Really to the object, not past its end). // Otherwise, it will work like __cxa_allocate_exception. void * __cxa_allocate_dependent_exception () { size_t actual_size = sizeof(__cxa_dependent_exception); diff --git a/lib/libcxxabi/src/cxa_exception.h b/lib/libcxxabi/src/cxa_exception.h index aba08f2992..fa4c4dc55b 100644 --- a/lib/libcxxabi/src/cxa_exception.h +++ b/lib/libcxxabi/src/cxa_exception.h @@ -47,10 +47,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { // In Wasm, a destructor returns its argument void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); #else - void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); + void (_LIBCXXABI_DTOR_FUNC *__ptrauth_cxxabi_exception_destructor exceptionDestructor)(void *); #endif - std::unexpected_handler unexpectedHandler; - std::terminate_handler terminateHandler; + std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler; + std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler; __cxa_exception *nextException; @@ -61,10 +61,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { int propagationCount; #else int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - void *catchTemp; - void *adjustedPtr; + const unsigned char *__ptrauth_cxxabi_action_record actionRecord; + const unsigned char *__ptrauth_cxxabi_lsd languageSpecificData; + void *__ptrauth_cxxabi_catch_temp catchTemp; + void *__ptrauth_cxxabi_adjusted_ptr adjustedPtr; #endif #if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI) @@ -79,6 +79,8 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html // The layout of this structure MUST match the layout of __cxa_exception, with // primaryException instead of referenceCount. +// The pointer authentication schemas specified here must also match those of +// the corresponding members in __cxa_exception. struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { #if defined(__LP64__) || defined(_WIN64) || defined(_LIBCXXABI_ARM_EHABI) void* reserve; // padding. @@ -86,9 +88,9 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { #endif std::type_info *exceptionType; - void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); - std::unexpected_handler unexpectedHandler; - std::terminate_handler terminateHandler; + void (_LIBCXXABI_DTOR_FUNC *__ptrauth_cxxabi_exception_destructor exceptionDestructor)(void *); + std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler; + std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler; __cxa_exception *nextException; @@ -99,10 +101,10 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { int propagationCount; #else int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - void * catchTemp; - void *adjustedPtr; + const unsigned char *__ptrauth_cxxabi_action_record actionRecord; + const unsigned char *__ptrauth_cxxabi_lsd languageSpecificData; + void *__ptrauth_cxxabi_catch_temp catchTemp; + void *__ptrauth_cxxabi_adjusted_ptr adjustedPtr; #endif #if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI) diff --git a/lib/libcxxabi/src/cxa_personality.cpp b/lib/libcxxabi/src/cxa_personality.cpp index 5f6e75c5be..77b2eb53af 100644 --- a/lib/libcxxabi/src/cxa_personality.cpp +++ b/lib/libcxxabi/src/cxa_personality.cpp @@ -20,7 +20,52 @@ #include "cxa_exception.h" #include "cxa_handlers.h" #include "private_typeinfo.h" -#include "unwind.h" + +#if __has_feature(ptrauth_calls) + +// CXXABI depends on defintions in libunwind as pointer auth couples the +// definitions +# include "libunwind.h" + +// The actual value of the discriminators listed below is not important. +// The derivation of the constants is only being included for the purpose +// of maintaining a record of how they were originally produced. + +// ptrauth_string_discriminator("scan_results::languageSpecificData") == 0xE50D) +# define __ptrauth_scan_results_lsd __ptrauth(ptrauth_key_process_dependent_code, 1, 0xE50D) + +// ptrauth_string_discriminator("scan_results::actionRecord") == 0x9823 +# define __ptrauth_scan_results_action_record __ptrauth(ptrauth_key_process_dependent_code, 1, 0x9823) + +// scan result is broken up as we have a manual re-sign that requires each component +# define __ptrauth_scan_results_landingpad_key ptrauth_key_process_dependent_code +// ptrauth_string_discriminator("scan_results::landingPad") == 0xD27C +# define __ptrauth_scan_results_landingpad_disc 0xD27C +# define __ptrauth_scan_results_landingpad \ + __ptrauth(__ptrauth_scan_results_landingpad_key, 1, __ptrauth_scan_results_landingpad_disc) + +// `__ptrauth_restricted_intptr` is a feature of apple clang that predates +// support for direct application of `__ptrauth` to integer types. This +// guard is necessary to support compilation with those compiler. +# if __has_extension(ptrauth_restricted_intptr_qualifier) +# define __ptrauth_scan_results_landingpad_intptr \ + __ptrauth_restricted_intptr(__ptrauth_scan_results_landingpad_key, 1, __ptrauth_scan_results_landingpad_disc) +# else +# define __ptrauth_scan_results_landingpad_intptr \ + __ptrauth(__ptrauth_scan_results_landingpad_key, 1, __ptrauth_scan_results_landingpad_disc) +# endif + +#else +# define __ptrauth_scan_results_lsd +# define __ptrauth_scan_results_action_record +# define __ptrauth_scan_results_landingpad +# define __ptrauth_scan_results_landingpad_intptr +#endif + +// The functions defined in this file are magic functions called only by the compiler. +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif // TODO: This is a temporary workaround for libc++abi to recognize that it's being // built against LLVM's libunwind. LLVM's libunwind started reporting _LIBUNWIND_VERSION @@ -527,12 +572,17 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception) namespace { +typedef const uint8_t *__ptrauth_scan_results_lsd lsd_ptr_t; +typedef const uint8_t *__ptrauth_scan_results_action_record action_ptr_t; +typedef uintptr_t __ptrauth_scan_results_landingpad_intptr landing_pad_t; +typedef void *__ptrauth_scan_results_landingpad landing_pad_ptr_t; + struct scan_results { int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup - const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. - const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected - uintptr_t landingPad; // null -> nothing found, else something found + action_ptr_t actionRecord; // Currently unused. Retained to ease future maintenance. + lsd_ptr_t languageSpecificData; // Needed only for __cxa_call_unexpected + landing_pad_t landingPad; // null -> nothing found, else something found void* adjustedPtr; // Used in cxa_exception.cpp _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, // _URC_FATAL_PHASE2_ERROR, @@ -557,7 +607,23 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, reinterpret_cast(unwind_exception)); _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), static_cast(results.ttypeIndex)); +#if __has_feature(ptrauth_calls) + auto stackPointer = _Unwind_GetGR(context, UNW_REG_SP); + // We manually re-sign the IP as the __ptrauth qualifiers cannot + // express the required relationship with the destination address + const auto existingDiscriminator = + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc); + unw_word_t newIP /* opaque __ptrauth(ptrauth_key_return_address, stackPointer, 0) */ = + (unw_word_t)ptrauth_auth_and_resign(*(void* const*)&results.landingPad, + __ptrauth_scan_results_landingpad_key, + existingDiscriminator, + ptrauth_key_return_address, + stackPointer); + _Unwind_SetIP(context, newIP); +#else _Unwind_SetIP(context, results.landingPad); +#endif } /* @@ -691,12 +757,12 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, // The call sites are ordered in increasing value of start uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding); uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding); - uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); + landing_pad_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); uintptr_t actionEntry = readULEB128(&callSitePtr); if ((start <= ipOffset) && (ipOffset < (start + length))) #else // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__ // ip is 1-based index into this table - uintptr_t landingPad = readULEB128(&callSitePtr); + landing_pad_t landingPad = readULEB128(&callSitePtr); uintptr_t actionEntry = readULEB128(&callSitePtr); if (--ip == 0) #endif // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__ @@ -903,6 +969,57 @@ _UA_CLEANUP_PHASE */ #if !defined(_LIBCXXABI_ARM_EHABI) + +// We use these helper functions to work around the behavior of casting between +// integers (even those that are authenticated) and authenticated pointers. +// Because the schemas being used are address discriminated we cannot use a +// trivial value union to coerce the types so instead we perform the re-signing +// manually. +using __cxa_catch_temp_type = decltype(__cxa_exception::catchTemp); +static inline void set_landing_pad(scan_results& results, + const __cxa_catch_temp_type& source) { +#if __has_feature(ptrauth_calls) + const uintptr_t sourceDiscriminator = + ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc); + const uintptr_t targetDiscriminator = + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc); + uintptr_t reauthenticatedLandingPad = + (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast(&source), + __ptrauth_cxxabi_catch_temp_key, + sourceDiscriminator, + __ptrauth_scan_results_landingpad_key, + targetDiscriminator); + memmove(reinterpret_cast(&results.landingPad), + reinterpret_cast(&reauthenticatedLandingPad), + sizeof(reauthenticatedLandingPad)); +#else + results.landingPad = reinterpret_cast(source); +#endif +} + +static inline void get_landing_pad(__cxa_catch_temp_type &dest, + const scan_results &results) { +#if __has_feature(ptrauth_calls) + const uintptr_t sourceDiscriminator = + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc); + const uintptr_t targetDiscriminator = + ptrauth_blend_discriminator(&dest, __ptrauth_cxxabi_catch_temp_disc); + uintptr_t reauthenticatedPointer = + (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast(&results.landingPad), + __ptrauth_scan_results_landingpad_key, + sourceDiscriminator, + __ptrauth_cxxabi_catch_temp_key, + targetDiscriminator); + memmove(reinterpret_cast(&dest), + reinterpret_cast(&reauthenticatedPointer), + sizeof(reauthenticatedPointer)); +#else + dest = reinterpret_cast<__cxa_catch_temp_type>(results.landingPad); +#endif +} + #ifdef __WASM_EXCEPTIONS__ _Unwind_Reason_Code __gxx_personality_wasm0 #elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) @@ -935,8 +1052,7 @@ __gxx_personality_v0 results.ttypeIndex = exception_header->handlerSwitchValue; results.actionRecord = exception_header->actionRecord; results.languageSpecificData = exception_header->languageSpecificData; - results.landingPad = - reinterpret_cast(exception_header->catchTemp); + set_landing_pad(results, exception_header->catchTemp); results.adjustedPtr = exception_header->adjustedPtr; // Jump to the handler. @@ -970,7 +1086,7 @@ __gxx_personality_v0 exc->handlerSwitchValue = static_cast(results.ttypeIndex); exc->actionRecord = results.actionRecord; exc->languageSpecificData = results.languageSpecificData; - exc->catchTemp = reinterpret_cast(results.landingPad); + get_landing_pad(exc->catchTemp, results); exc->adjustedPtr = results.adjustedPtr; #ifdef __WASM_EXCEPTIONS__ // Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the @@ -1009,9 +1125,6 @@ __gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame, #else -extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, - _Unwind_Context*); - // Helper function to unwind one frame. // ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the // personality routine should update the virtual register set (VRS) according to the diff --git a/lib/libcxxabi/src/cxa_thread_atexit.cpp b/lib/libcxxabi/src/cxa_thread_atexit.cpp index 8546cfe48c..402a52c741 100644 --- a/lib/libcxxabi/src/cxa_thread_atexit.cpp +++ b/lib/libcxxabi/src/cxa_thread_atexit.cpp @@ -106,6 +106,7 @@ namespace { #endif // HAVE___CXA_THREAD_ATEXIT_IMPL +#if defined(__linux__) || defined(__Fuchsia__) extern "C" { _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void* obj, void* dso_symbol) throw() { @@ -140,6 +141,6 @@ extern "C" { } #endif // HAVE___CXA_THREAD_ATEXIT_IMPL } - } // extern "C" +#endif // defined(__linux__) || defined(__Fuchsia__) } // namespace __cxxabiv1 diff --git a/lib/libcxxabi/src/demangle/DemangleConfig.h b/lib/libcxxabi/src/demangle/DemangleConfig.h index 7904e9d1eb..79dbeb89cc 100644 --- a/lib/libcxxabi/src/demangle/DemangleConfig.h +++ b/lib/libcxxabi/src/demangle/DemangleConfig.h @@ -115,4 +115,8 @@ #define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle { #define DEMANGLE_NAMESPACE_END } } +// The DEMANGLE_ABI macro resolves to nothing when building libc++abi. Only +// the llvm copy defines DEMANGLE_ABI as a visibility attribute. +#define DEMANGLE_ABI + #endif // LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H diff --git a/lib/libcxxabi/src/demangle/ItaniumDemangle.h b/lib/libcxxabi/src/demangle/ItaniumDemangle.h index b306b20134..b999438ff2 100644 --- a/lib/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/lib/libcxxabi/src/demangle/ItaniumDemangle.h @@ -1366,7 +1366,7 @@ public: template void match(Fn F) const { F(Name, Params, Requires); } void printLeft(OutputBuffer &OB) const override { - ScopedOverride LT(OB.GtIsGt, 0); + ScopedOverride LT(OB.TemplateTracker.InsideTemplate, true); OB += "template<"; Params.printWithComma(OB); OB += "> typename "; @@ -1550,7 +1550,7 @@ public: NodeArray getParams() { return Params; } void printLeft(OutputBuffer &OB) const override { - ScopedOverride LT(OB.GtIsGt, 0); + ScopedOverride LT(OB.TemplateTracker.InsideTemplate, true); OB += "<"; Params.printWithComma(OB); OB += ">"; @@ -1824,7 +1824,7 @@ public: void printDeclarator(OutputBuffer &OB) const { if (!TemplateParams.empty()) { - ScopedOverride LT(OB.GtIsGt, 0); + ScopedOverride LT(OB.TemplateTracker.InsideTemplate, true); OB += "<"; TemplateParams.printWithComma(OB); OB += ">"; @@ -1885,7 +1885,9 @@ public: } void printLeft(OutputBuffer &OB) const override { - bool ParenAll = OB.isGtInsideTemplateArgs() && + // If we're printing a '<' inside of a template argument, and we haven't + // yet parenthesized the expression, do so now. + bool ParenAll = !OB.isInParensInTemplateArgs() && (InfixOperator == ">" || InfixOperator == ">>"); if (ParenAll) OB.printOpen(); @@ -2061,7 +2063,7 @@ public: void printLeft(OutputBuffer &OB) const override { OB += CastKind; { - ScopedOverride LT(OB.GtIsGt, 0); + ScopedOverride LT(OB.TemplateTracker.InsideTemplate, true); OB += "<"; OB.printLeft(*To); OB += ">"; @@ -3049,7 +3051,8 @@ template struct AbstractManglingParser { Node *parse(bool ParseParams = true); }; -const char* parse_discriminator(const char* first, const char* last); +DEMANGLE_ABI const char *parse_discriminator(const char *first, + const char *last); // ::= // N // ::= # See Scope Encoding below // Z diff --git a/lib/libcxxabi/src/demangle/Utility.h b/lib/libcxxabi/src/demangle/Utility.h index 8829f3fa13..df5b54dca4 100644 --- a/lib/libcxxabi/src/demangle/Utility.h +++ b/lib/libcxxabi/src/demangle/Utility.h @@ -81,7 +81,7 @@ public: OutputBuffer(const OutputBuffer &) = delete; OutputBuffer &operator=(const OutputBuffer &) = delete; - virtual ~OutputBuffer() {} + virtual ~OutputBuffer() = default; operator std::string_view() const { return std::string_view(Buffer, CurrentPosition); @@ -104,18 +104,32 @@ public: unsigned CurrentPackIndex = std::numeric_limits::max(); unsigned CurrentPackMax = std::numeric_limits::max(); - /// When zero, we're printing template args and '>' needs to be parenthesized. - /// Use a counter so we can simply increment inside parentheses. - unsigned GtIsGt = 1; + struct { + /// The depth of '(' and ')' inside the currently printed template + /// arguments. + unsigned ParenDepth = 0; - bool isGtInsideTemplateArgs() const { return GtIsGt == 0; } + /// True if we're currently printing a template argument. + bool InsideTemplate = false; + } TemplateTracker; + + /// Returns true if we're currently between a '(' and ')' when printing + /// template args. + bool isInParensInTemplateArgs() const { + return TemplateTracker.ParenDepth > 0; + } + + /// Returns true if we're printing template args. + bool isInsideTemplateArgs() const { return TemplateTracker.InsideTemplate; } void printOpen(char Open = '(') { - GtIsGt++; + if (isInsideTemplateArgs()) + TemplateTracker.ParenDepth++; *this += Open; } void printClose(char Close = ')') { - GtIsGt--; + if (isInsideTemplateArgs()) + TemplateTracker.ParenDepth--; *this += Close; } diff --git a/lib/libcxxabi/src/fallback_malloc.cpp b/lib/libcxxabi/src/fallback_malloc.cpp index 75788fe9be..6a261e6f00 100644 --- a/lib/libcxxabi/src/fallback_malloc.cpp +++ b/lib/libcxxabi/src/fallback_malloc.cpp @@ -16,7 +16,7 @@ #endif #endif -#include <__memory/aligned_alloc.h> +#include "include/aligned_alloc.h" // from libc++ #include <__assert> #include // for malloc, calloc, free #include // for memset diff --git a/lib/libcxxabi/src/private_typeinfo.cpp b/lib/libcxxabi/src/private_typeinfo.cpp index 01a1d2603b..d185f2618a 100644 --- a/lib/libcxxabi/src/private_typeinfo.cpp +++ b/lib/libcxxabi/src/private_typeinfo.cpp @@ -831,6 +831,10 @@ bool __pointer_to_member_type_info::can_catch_nested( #pragma clang diagnostic ignored "-Wmissing-field-initializers" #endif +#pragma GCC diagnostic push +// __dynamic_cast is called by the compiler, so there is no prototype +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + // __dynamic_cast // static_ptr: pointer to an object of type static_type; nonnull, and since the @@ -953,6 +957,8 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type, return const_cast(dst_ptr); } +#pragma GCC diagnostic pop + #ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/lib/libcxxabi/src/stdlib_new_delete.cpp b/lib/libcxxabi/src/stdlib_new_delete.cpp index b5ed59958d..783357c435 100644 --- a/lib/libcxxabi/src/stdlib_new_delete.cpp +++ b/lib/libcxxabi/src/stdlib_new_delete.cpp @@ -8,8 +8,8 @@ #include "__cxxabi_config.h" #include "abort_message.h" +#include "include/aligned_alloc.h" // from libc++ #include "include/overridable_function.h" // from libc++ -#include <__memory/aligned_alloc.h> #include #include #include @@ -63,7 +63,7 @@ static void* operator_new_impl(std::size_t size) { return p; } -_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC { +OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC { void* p = operator_new_impl(size); if (p == nullptr) __throw_bad_alloc_shim(); @@ -94,7 +94,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { #endif } -_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { return ::operator new(size); } +OVERRIDABLE_FUNCTION void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); } _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { #if !_LIBCPP_HAS_EXCEPTIONS @@ -154,7 +154,7 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm return p; } -_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC { +OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { void* p = operator_new_aligned_impl(size, alignment); if (p == nullptr) __throw_bad_alloc_shim(); @@ -185,7 +185,7 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s # endif } -_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC { +OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { return ::operator new(size, alignment); }