@@ -89,6 +89,17 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, const char *kind,
8989 }
9090}
9191
92+ SANITIZER_INTERFACE_WEAK_DEF (void , __ubsan_report_error_preserve,
93+ const char *kind, uintptr_t caller,
94+ const uintptr_t *address)
95+ [[clang::preserve_all]] {
96+ // Additional indirecton so the user can override this with their own
97+ // preserve_all function. This would allow, e.g., a function that reports the
98+ // first error only, so for all subsequent calls we can skip the register save
99+ // / restore.
100+ __ubsan_report_error (kind, caller, address);
101+ }
102+
92103SANITIZER_INTERFACE_WEAK_DEF (void , __ubsan_report_error_fatal, const char *kind,
93104 uintptr_t caller, const uintptr_t *address) {
94105 // Use another handlers, in case it's already overriden.
@@ -130,6 +141,10 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
130141#define HANDLER_RECOVER (name, kind ) \
131142 INTERFACE void __ubsan_handle_##name##_minimal() { \
132143 __ubsan_report_error (kind, GET_CALLER_PC (), nullptr ); \
144+ } \
145+ INTERFACE void __ubsan_handle_##name##_minimal_preserve() \
146+ [[clang::preserve_all]] { \
147+ __ubsan_report_error_preserve (kind, GET_CALLER_PC (), nullptr ); \
133148 }
134149
135150#define HANDLER_NORECOVER (name, kind ) \
@@ -146,6 +161,10 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
146161#define HANDLER_RECOVER_PTR (name, kind ) \
147162 INTERFACE void __ubsan_handle_##name##_minimal(const uintptr_t address) { \
148163 __ubsan_report_error (kind, GET_CALLER_PC (), &address); \
164+ } \
165+ INTERFACE void __ubsan_handle_##name##_minimal_preserve( \
166+ const uintptr_t address) [[clang::preserve_all]] { \
167+ __ubsan_report_error_preserve (kind, GET_CALLER_PC (), &address); \
149168 }
150169
151170#define HANDLER_NORECOVER_PTR (name, kind ) \
0 commit comments