> On 14 Nov 2025, at 01:08, Richard Biener <[email protected]> wrote:
>
> On Fri, 14 Nov 2025, Jakub Jelinek wrote:
>
>> Hi!
>>
>> Attached is a libsanitizer update.
>> The attached patch (xz -9e compressed, to be applied first) is the
>> result of running libsanitizer merge.sh script, the included
>> patch below is a new local patch (merge of the two current
>> LOCAL_PATCHES). I had to resolve some Mac related conflicts, hope
>> I got it right, but I don't have Darwin nor experience with it.
>>
>> I went through abilists of all the libraries on x86_64-linux and
>> all I see is some additions of symbols (except for libubsan which
>> adds one new entrypoint which we don't use everything is additions
>> of new intercepted routines (so some new __intercept_* and corresponding
>> * exports).
>> Tested on x86_64-linux and i686-linux, the only regression is
>> FAIL: c-c++-common/asan/asan-stack-small.c -O2 -flto
>> -fno-use-linker-plugin -flto-partition=none execution test
>> but that seems like the test flaw:
>> char a;
>> char b;
>> char c;
>> pa = &a;
>> pb = &b;
>> pc = &c;
>> access (pb);
>> access (pc);
>> // access 'b' here
>> access (pa + 32);
>> The test assumes that the variables are laid out in the a, b, c
>> order, but that is clearly not what's happening as the report is:
>> This frame has 3 object(s):
>> [32, 33) 'c' (line 16)
>> [48, 49) 'b' (line 15)
>> [64, 65) 'a' (line 14) <== Memory access at offset 96 overflows this
>> variable
>> =>0x7b6566bf0000: f1 f1 f1 f1 01 f2 01 f2 01 f3 f3 f3[f3]f3 f3 f3
>> So, I think the test should do something like
>> if ((uintptr_t) pb == (uintptr_t) pa + 32)
>> access (pa + 32);
>> else if ((uintptr_t) pb == (uintptr_t) pa - 32)
>> access (pa - 32);
>> or so.
>>
>> Iain, could you please test this on Darwin?
>>
>> Ok for trunk?
>
> LGTM besides Iains input.
I am OOO will test (hopefully) on Monday.
Iain
> Richard.
>
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
>> index 351e00db6fb..80ae31e938a 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
>> @@ -41,10 +41,18 @@ static bool FrameIsInternal(const SymbolizedStack
>> *frame) {
>> return true;
>> if (file && internal_strstr(file, "\\compiler-rt\\lib\\"))
>> return true;
>> + if (file && internal_strstr(file, "\\libsanitizer\\"))
>> + return true;
>> if (module && (internal_strstr(module, "libclang_rt.")))
>> return true;
>> if (module && (internal_strstr(module, "clang_rt.")))
>> return true;
>> + if (module && (internal_strstr(module, "libtsan.")
>> + || internal_strstr(module, "libhwasan.")
>> + || internal_strstr(module, "liblsan.")
>> + || internal_strstr(module, "libasan.")
>> + || internal_strstr(module, "libubsan.")))
>> + return true;
>> return false;
>> }
>>
>> diff --git a/libsanitizer/asan/asan_globals.cpp
>> b/libsanitizer/asan/asan_globals.cpp
>> index c83b782cb85..d1794ad96e2 100644
>> --- a/libsanitizer/asan/asan_globals.cpp
>> +++ b/libsanitizer/asan/asan_globals.cpp
>> @@ -226,25 +226,6 @@ static void CheckODRViolationViaIndicator(const Global
>> *g)
>> AddGlobalToList(relevant_globals, g);
>> }
>>
>> -// Check ODR violation for given global G by checking if it's already
>> poisoned.
>> -// We use this method in case compiler doesn't use private aliases for
>> global
>> -// variables.
>> -static void CheckODRViolationViaPoisoning(const Global *g)
>> - SANITIZER_REQUIRES(mu_for_globals) {
>> - if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
>> - // This check may not be enough: if the first global is much larger
>> - // the entire redzone of the second global may be within the first
>> global.
>> - for (const auto &l : list_of_all_globals) {
>> - if (g->beg == l.g->beg &&
>> - (flags()->detect_odr_violation >= 2 || g->size != l.g->size) &&
>> - !IsODRViolationSuppressed(g->name)) {
>> - ReportODRViolation(g, FindRegistrationSite(g), l.g,
>> - FindRegistrationSite(l.g));
>> - }
>> - }
>> - }
>> -}
>> -
>> // Clang provides two different ways for global variables protection:
>> // it can poison the global itself or its private alias. In former
>> // case we may poison same symbol multiple times, that can help us to
>> @@ -290,8 +271,6 @@ static void RegisterGlobal(const Global *g)
>> SANITIZER_REQUIRES(mu_for_globals) {
>> // where two globals with the same name are defined in different modules.
>> if (UseODRIndicator(g))
>> CheckODRViolationViaIndicator(g);
>> - else
>> - CheckODRViolationViaPoisoning(g);
>> }
>> if (CanPoisonMemory())
>> PoisonRedZones(*g);
>> diff --git a/libsanitizer/asan/asan_interceptors.h
>> b/libsanitizer/asan/asan_interceptors.h
>> index 826b45f5ada..652379d39a3 100644
>> --- a/libsanitizer/asan/asan_interceptors.h
>> +++ b/libsanitizer/asan/asan_interceptors.h
>> @@ -71,7 +71,12 @@ void InitializePlatformInterceptors();
>> #if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \
>> (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__)))
>> # define ASAN_INTERCEPT___CXA_THROW 1
>> -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
>> +# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \
>> + || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION
>> +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
>> +# else
>> +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
>> +# endif
>> # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
>> # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
>> # else
>> diff --git a/libsanitizer/asan/asan_mapping.h
>> b/libsanitizer/asan/asan_mapping.h
>> index 91fe60db632..54890ca1789 100644
>> --- a/libsanitizer/asan/asan_mapping.h
>> +++ b/libsanitizer/asan/asan_mapping.h
>> @@ -193,7 +193,7 @@
>> # elif defined(__aarch64__)
>> # define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
>> # elif defined(__powerpc64__)
>> -# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
>> +# define ASAN_SHADOW_OFFSET_CONST 0x0000020000000000
>> # elif defined(__s390x__)
>> # define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
>> # elif SANITIZER_FREEBSD
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
>> index 525bc103861..ed19e4031a5 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
>> @@ -901,9 +901,13 @@ u32 GetNumberOfCPUs() {
>> # elif SANITIZER_SOLARIS
>> return sysconf(_SC_NPROCESSORS_ONLN);
>> # else
>> +# if defined(CPU_COUNT)
>> cpu_set_t CPUs;
>> CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);
>> return CPU_COUNT(&CPUs);
>> +# else
>> + return 1;
>> +# endif
>> # endif
>> }
>>
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
>> index 26d2e8d4ed7..d2144546cb0 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
>> @@ -71,7 +71,15 @@ extern char ***_NSGetArgv(void);
>> # include <mach/mach_time.h>
>> # include <mach/vm_statistics.h>
>> # include <malloc/malloc.h>
>> -# include <os/log.h>
>> +# if defined(__has_builtin) && __has_builtin(__builtin_os_log_format)
>> +# include <os/log.h>
>> +# else
>> + /* Without support for __builtin_os_log_format, fall back to the older
>> + method. */
>> +# define OS_LOG_DEFAULT 0
>> +# define os_log_error(A,B,C) \
>> + asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", (C));
>> +# endif
>> # include <pthread.h>
>> # include <pthread/introspection.h>
>> # include <sched.h>
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h
>> b/libsanitizer/sanitizer_common/sanitizer_mac.h
>> index f0a97d098ee..1cf2e298cc9 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_mac.h
>> +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h
>> @@ -14,6 +14,26 @@
>>
>> #include "sanitizer_common.h"
>> #include "sanitizer_platform.h"
>> +
>> +/* TARGET_OS_OSX is not present in SDKs before Darwin16 (macOS 10.12) use
>> + TARGET_OS_MAC (we have no support for iOS in any form for these versions,
>> + so there's no ambiguity). */
>> +#if !defined(TARGET_OS_OSX) && TARGET_OS_MAC
>> +# define TARGET_OS_OSX 1
>> +#endif
>> +
>> +/* Other TARGET_OS_xxx are not present on earlier versions, define them to
>> + 0 (we have no support for them; they are not valid targets anyway). */
>> +#ifndef TARGET_OS_IOS
>> +#define TARGET_OS_IOS 0
>> +#endif
>> +#ifndef TARGET_OS_TV
>> +#define TARGET_OS_TV 0
>> +#endif
>> +#ifndef TARGET_OS_WATCH
>> +#define TARGET_OS_WATCH 0
>> +#endif
>> +
>> #if SANITIZER_APPLE
>> #include "sanitizer_posix.h"
>>
>> diff --git
>> a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
>> index bf0f355847c..c278c8797f7 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
>> @@ -26,7 +26,10 @@
>>
>> // With old kernels (and even new kernels on powerpc) asm/stat.h uses types
>> that
>> // are not defined anywhere in userspace headers. Fake them. This seems to
>> work
>> -// fine with newer headers, too.
>> +// fine with newer headers, too. Beware that with <sys/stat.h>, struct stat
>> +// takes the form of struct stat64 on 32-bit platforms if
>> _FILE_OFFSET_BITS=64.
>> +// Also, for some platforms (e.g. mips) there are additional members in the
>> +// <sys/stat.h> struct stat:s.
>> #include <linux/posix_types.h>
>> # if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__)
>> # include <sys/stat.h>
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
>> index 5ff8d183255..64e9c4858b6 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
>> @@ -197,8 +197,13 @@ static bool IsDyldHdr(const mach_header
>> // until we hit a Mach header matching dyld instead. These recurse
>> // calls are expensive, but the first memory map generation occurs
>> // early in the process, when dyld is one of the only images loaded,
>> -// so it will be hit after only a few iterations. These assumptions don't
>> hold
>> -// on macOS 13+ anymore (dyld itself has moved into the shared cache).
>> +// so it will be hit after only a few iterations. These assumptions don't
>> +// hold on macOS 13+ anymore (dyld itself has moved into the shared cache).
>> +
>> +// FIXME: Unfortunately, the upstream revised version to deal with macOS 13+
>> +// is incompatible with GCC and also uses APIs not available on earlier
>> +// systems which we support; backed out for now.
>> +
>> static mach_header *GetDyldImageHeaderViaVMRegion() {
>> vm_address_t address = 0;
>>
>> @@ -222,65 +227,17 @@ static mach_header *GetDyldImageHeaderVi
>> }
>> }
>>
>> -extern "C" {
>> -struct dyld_shared_cache_dylib_text_info {
>> - uint64_t version; // current version 2
>> - // following fields all exist in version 1
>> - uint64_t loadAddressUnslid;
>> - uint64_t textSegmentSize;
>> - uuid_t dylibUuid;
>> - const char *path; // pointer invalid at end of iterations
>> - // following fields all exist in version 2
>> - uint64_t textSegmentOffset; // offset from start of cache
>> -};
>> -typedef struct dyld_shared_cache_dylib_text_info
>> - dyld_shared_cache_dylib_text_info;
>> -
>> -extern bool _dyld_get_shared_cache_uuid(uuid_t uuid);
>> -extern const void *_dyld_get_shared_cache_range(size_t *length);
>> -extern intptr_t _dyld_get_image_slide(const struct mach_header* mh);
>> -extern int dyld_shared_cache_iterate_text(
>> - const uuid_t cacheUuid,
>> - void (^callback)(const dyld_shared_cache_dylib_text_info *info));
>> -} // extern "C"
>> -
>> -static mach_header *GetDyldImageHeaderViaSharedCache() {
>> - uuid_t uuid;
>> - bool hasCache = _dyld_get_shared_cache_uuid(uuid);
>> - if (!hasCache)
>> - return nullptr;
>> -
>> - size_t cacheLength;
>> - __block uptr cacheStart =
>> (uptr)_dyld_get_shared_cache_range(&cacheLength);
>> - CHECK(cacheStart && cacheLength);
>> -
>> - __block mach_header *dyldHdr = nullptr;
>> - int res = dyld_shared_cache_iterate_text(
>> - uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
>> - CHECK_GE(info->version, 2);
>> - mach_header *hdr =
>> - (mach_header *)(cacheStart + info->textSegmentOffset);
>> - if (IsDyldHdr(hdr))
>> - dyldHdr = hdr;
>> - });
>> - CHECK_EQ(res, 0);
>> -
>> - return dyldHdr;
>> -}
>> -
>> const mach_header *get_dyld_hdr() {
>> if (!dyld_hdr) {
>> // On macOS 13+, dyld itself has moved into the shared cache. Looking
>> it up
>> // via vm_region_recurse_64() causes spins/hangs/crashes.
>> + // FIXME: find a way to do this compatible with GCC.
>> if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) {
>> - dyld_hdr = GetDyldImageHeaderViaSharedCache();
>> - if (!dyld_hdr) {
>> VReport(1,
>> - "Failed to lookup the dyld image header in the shared cache
>> on "
>> - "macOS 13+ (or no shared cache in use). Falling back to "
>> + "looking up the dyld image header in the shared cache on "
>> + "macOS 13+ is not yet supported. Falling back to "
>> "lookup via vm_region_recurse_64().\n");
>> dyld_hdr = GetDyldImageHeaderViaVMRegion();
>> - }
>> } else {
>> dyld_hdr = GetDyldImageHeaderViaVMRegion();
>> }
>> diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
>> b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
>> index d24fae98213..661495e2340 100644
>> --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
>> +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
>> @@ -87,8 +87,8 @@ static inline uhwptr *GetCanonicFrame(uptr bp,
>> // Nope, this does not look right either. This means the frame after next
>> does
>> // not have a valid frame pointer, but we can still extract the caller PC.
>> // Unfortunately, there is no way to decide between GCC and LLVM frame
>> - // layouts. Assume LLVM.
>> - return bp_prev;
>> + // layouts. Assume GCC.
>> + return bp_prev - 1;
>> #else
>> return (uhwptr*)bp;
>> #endif
>> @@ -111,14 +111,21 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp,
>> uptr stack_top,
>> IsAligned((uptr)frame, sizeof(*frame)) &&
>> size < max_depth) {
>> #ifdef __powerpc__
>> - // PowerPC ABIs specify that the return address is saved at offset
>> - // 16 of the *caller's* stack frame. Thus we must dereference the
>> - // back chain to find the caller frame before extracting it.
>> + // PowerPC ABIs specify that the return address is saved on the
>> + // *caller's* stack frame. Thus we must dereference the back chain
>> + // to find the caller frame before extracting it.
>> uhwptr *caller_frame = (uhwptr*)frame[0];
>> if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||
>> !IsAligned((uptr)caller_frame, sizeof(uhwptr)))
>> break;
>> + // For most ABIs the offset where the return address is saved is two
>> + // register sizes. The exception is the SVR4 ABI, which uses an
>> + // offset of only one register size.
>> +#ifdef _CALL_SYSV
>> + uhwptr pc1 = caller_frame[1];
>> +#else
>> uhwptr pc1 = caller_frame[2];
>> +#endif
>> #elif defined(__s390__)
>> uhwptr pc1 = frame[14];
>> #elif defined(__loongarch__) || defined(__riscv)
>> diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S
>> b/libsanitizer/tsan/tsan_rtl_ppc64.S
>> index 8285e21aa1e..9e533a71a9c 100644
>> --- a/libsanitizer/tsan/tsan_rtl_ppc64.S
>> +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S
>> @@ -1,5 +1,6 @@
>> #include "tsan_ppc_regs.h"
>>
>> + .machine altivec
>> .section .text
>> .hidden __tsan_setjmp
>> .globl _setjmp
>> diff --git a/libsanitizer/ubsan/ubsan_flags.cpp
>> b/libsanitizer/ubsan/ubsan_flags.cpp
>> index 25cefd46ce2..9a66bd37518 100644
>> --- a/libsanitizer/ubsan/ubsan_flags.cpp
>> +++ b/libsanitizer/ubsan/ubsan_flags.cpp
>> @@ -50,6 +50,7 @@ void InitializeFlags() {
>> {
>> CommonFlags cf;
>> cf.CopyFrom(*common_flags());
>> + cf.print_summary = false;
>> cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH");
>> OverrideCommonFlags(cf);
>> }
>> diff --git a/libsanitizer/ubsan/ubsan_handlers.cpp
>> b/libsanitizer/ubsan/ubsan_handlers.cpp
>> index a419cf0b2b5..ea332013a50 100644
>> --- a/libsanitizer/ubsan/ubsan_handlers.cpp
>> +++ b/libsanitizer/ubsan/ubsan_handlers.cpp
>> @@ -904,6 +904,21 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData
>> *Data, ValueHandle Vtable,
>>
>> } // namespace __ubsan
>>
>> +void __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *CallData,
>> + ValueHandle Function) {
>> + GET_REPORT_OPTIONS(false);
>> + CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
>> + handleCFIBadIcall(&Data, Function, Opts);
>> +}
>> +
>> +void __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *CallData,
>> + ValueHandle Function) {
>> + GET_REPORT_OPTIONS(true);
>> + CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
>> + handleCFIBadIcall(&Data, Function, Opts);
>> + Die();
>> +}
>> +
>> void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data,
>> ValueHandle Value,
>> uptr ValidVtable) {
>> diff --git a/libsanitizer/ubsan/ubsan_handlers.h
>> b/libsanitizer/ubsan/ubsan_handlers.h
>> index 4ffa1439a13..f99948ff498 100644
>> --- a/libsanitizer/ubsan/ubsan_handlers.h
>> +++ b/libsanitizer/ubsan/ubsan_handlers.h
>> @@ -217,12 +217,20 @@ enum CFITypeCheckKind : unsigned char {
>> CFITCK_VMFCall,
>> };
>>
>> +struct CFIBadIcallData {
>> + SourceLocation Loc;
>> + const TypeDescriptor &Type;
>> +};
>> +
>> struct CFICheckFailData {
>> CFITypeCheckKind CheckKind;
>> SourceLocation Loc;
>> const TypeDescriptor &Type;
>> };
>>
>> +/// \brief Handle control flow integrity failure for indirect function
>> calls.
>> +RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function)
>> +
>> /// \brief Handle control flow integrity failures.
>> RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function,
>> uptr VtableIsValid)
>> diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
>> b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
>> index 206a0bb485a..0317a3d1428 100644
>> --- a/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
>> +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
>> @@ -156,6 +156,50 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData
>> *Data, ValueHandle Vtable,
>> Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
>> << SrcModule << DstModule;
>> }
>> +
>> +static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
>> + ValueHandle Function,
>> + ValueHandle calleeRTTI,
>> + ValueHandle fnRTTI, ReportOptions
>> Opts) {
>> + if (checkTypeInfoEquality(reinterpret_cast<void *>(calleeRTTI),
>> + reinterpret_cast<void *>(fnRTTI)))
>> + return false;
>> +
>> + SourceLocation CallLoc = Data->Loc.acquire();
>> + ErrorType ET = ErrorType::FunctionTypeMismatch;
>> +
>> + if (ignoreReport(CallLoc, Opts, ET))
>> + return true;
>> +
>> + ScopedReport R(Opts, CallLoc, ET);
>> +
>> + SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
>> + const char *FName = FLoc.get()->info.function;
>> + if (!FName)
>> + FName = "(unknown)";
>> +
>> + Diag(CallLoc, DL_Error, ET,
>> + "call to function %0 through pointer to incorrect function type %1")
>> + << FName << Data->Type;
>> + Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
>> + return true;
>> +}
>> +
>> +void __ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData
>> *Data,
>> + ValueHandle Function,
>> + ValueHandle calleeRTTI,
>> + ValueHandle fnRTTI) {
>> + GET_REPORT_OPTIONS(false);
>> + handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts);
>> +}
>> +
>> +void __ubsan_handle_function_type_mismatch_v1_abort(
>> + FunctionTypeMismatchData *Data, ValueHandle Function,
>> + ValueHandle calleeRTTI, ValueHandle fnRTTI) {
>> + GET_REPORT_OPTIONS(true);
>> + if (handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts))
>> + Die();
>> +}
>> } // namespace __ubsan
>>
>> #endif // CAN_SANITIZE_UB
>> diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.h
>> b/libsanitizer/ubsan/ubsan_handlers_cxx.h
>> index 71695cbdc09..f6f24e8d63c 100644
>> --- a/libsanitizer/ubsan/ubsan_handlers_cxx.h
>> +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.h
>> @@ -33,6 +33,19 @@ void __ubsan_handle_dynamic_type_cache_miss(
>> extern "C" SANITIZER_INTERFACE_ATTRIBUTE
>> void __ubsan_handle_dynamic_type_cache_miss_abort(
>> DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
>> +
>> +struct FunctionTypeMismatchData;
>> +
>> +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
>> +__ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data,
>> + ValueHandle Val,
>> + ValueHandle calleeRTTI,
>> + ValueHandle fnRTTI);
>> +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
>> +__ubsan_handle_function_type_mismatch_v1_abort(FunctionTypeMismatchData
>> *Data,
>> + ValueHandle Val,
>> + ValueHandle calleeRTTI,
>> + ValueHandle fnRTTI);
>> }
>>
>> #endif // UBSAN_HANDLERS_CXX_H
>> diff --git a/libsanitizer/ubsan/ubsan_interface.inc
>> b/libsanitizer/ubsan/ubsan_interface.inc
>> index cb27feb5d7e..f95f71af3ed 100644
>> --- a/libsanitizer/ubsan/ubsan_interface.inc
>> +++ b/libsanitizer/ubsan/ubsan_interface.inc
>> @@ -21,6 +21,8 @@ INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss)
>> INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort)
>> INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow)
>> INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
>> +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1)
>> +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort)
>> INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
>> INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
>> INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
>> diff --git a/libsanitizer/ubsan/ubsan_platform.h
>> b/libsanitizer/ubsan/ubsan_platform.h
>> index d2cc2e10bd2..ad3e883f0f3 100644
>> --- a/libsanitizer/ubsan/ubsan_platform.h
>> +++ b/libsanitizer/ubsan/ubsan_platform.h
>> @@ -12,6 +12,7 @@
>> #ifndef UBSAN_PLATFORM_H
>> #define UBSAN_PLATFORM_H
>>
>> +#ifndef CAN_SANITIZE_UB
>> // Other platforms should be easy to add, and probably work as-is.
>> #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||
>> \
>> defined(__NetBSD__) || defined(__DragonFly__) ||
>> \
>> @@ -21,5 +22,6 @@
>> #else
>> # define CAN_SANITIZE_UB 0
>> #endif
>> +#endif //CAN_SANITIZE_UB
>>
>> #endif
>>
>>
>> Jakub
>>
>
> --
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)