commit 80212b03ff792ddfff82092b35aa7ed0fdf937a8 (tree)
parent 520af6966041b891442ab34ac13b0f6861a09fc0
Author: Alex Rønne Petersen <alex@alexrp.com>
Date: Sat, 17 Jan 2026 05:25:15 +0100
libcxxabi: update to LLVM 22
Diffstat:
11 files changed, 235 insertions(+), 71 deletions(-)
diff --git 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(<ptrauth.h>)
+# include <ptrauth.h>
+#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
@@ -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<void*>(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
@@ -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
@@ -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<uintptr_t>(unwind_exception));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
static_cast<uintptr_t>(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<void* const*>(&source),
+ __ptrauth_cxxabi_catch_temp_key,
+ sourceDiscriminator,
+ __ptrauth_scan_results_landingpad_key,
+ targetDiscriminator);
+ memmove(reinterpret_cast<void *>(&results.landingPad),
+ reinterpret_cast<void *>(&reauthenticatedLandingPad),
+ sizeof(reauthenticatedLandingPad));
+#else
+ results.landingPad = reinterpret_cast<landing_pad_t>(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<void* const*>(&results.landingPad),
+ __ptrauth_scan_results_landingpad_key,
+ sourceDiscriminator,
+ __ptrauth_cxxabi_catch_temp_key,
+ targetDiscriminator);
+ memmove(reinterpret_cast<void *>(&dest),
+ reinterpret_cast<void *>(&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<uintptr_t>(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<int>(results.ttypeIndex);
exc->actionRecord = results.actionRecord;
exc->languageSpecificData = results.languageSpecificData;
- exc->catchTemp = reinterpret_cast<void*>(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
@@ -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
@@ -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
@@ -1366,7 +1366,7 @@ public:
template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
void printLeft(OutputBuffer &OB) const override {
- ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
+ ScopedOverride<bool> 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<unsigned> LT(OB.GtIsGt, 0);
+ ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
OB += "<";
Params.printWithComma(OB);
OB += ">";
@@ -1824,7 +1824,7 @@ public:
void printDeclarator(OutputBuffer &OB) const {
if (!TemplateParams.empty()) {
- ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
+ ScopedOverride<bool> 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<unsigned> LT(OB.GtIsGt, 0);
+ ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
OB += "<";
OB.printLeft(*To);
OB += ">";
@@ -3049,7 +3051,8 @@ template <typename Derived, typename Alloc> 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);
// <name> ::= <nested-name> // N
// ::= <local-name> # See Scope Encoding below // Z
diff --git 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<unsigned>::max();
unsigned CurrentPackMax = std::numeric_limits<unsigned>::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
@@ -16,7 +16,7 @@
#endif
#endif
-#include <__memory/aligned_alloc.h>
+#include "include/aligned_alloc.h" // from libc++
#include <__assert>
#include <stdlib.h> // for malloc, calloc, free
#include <string.h> // for memset
diff --git 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<void*>(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
@@ -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 <cstddef>
#include <cstdlib>
#include <new>
@@ -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);
}