> 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)


Reply via email to