diff --git a/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h b/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h --- a/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h +++ b/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h @@ -51,11 +51,18 @@ #define DISPATCH_DATA_DESTRUCTOR_MUNMAP _dispatch_data_destructor_munmap #if __has_attribute(noescape) - #define DISPATCH_NOESCAPE __attribute__((__noescape__)) +# define DISPATCH_NOESCAPE __attribute__((__noescape__)) #else - #define DISPATCH_NOESCAPE +# define DISPATCH_NOESCAPE #endif +#if SANITIZER_MAC +# define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak_import)) +#else +# define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak)) +#endif + + // Data types used in dispatch APIs typedef unsigned long size_t; typedef unsigned long uintptr_t; diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp @@ -219,8 +219,19 @@ DISPATCH_INTERCEPT(dispatch, false) DISPATCH_INTERCEPT(dispatch_barrier, true) -DISPATCH_INTERCEPT_SYNC_F(dispatch_async_and_wait_f, false) +// dispatch_async_and_wait[_f] was introduced in macOS 10.14, which is greater +// than our minimal deployment target. We need to forward declare it as a "weak +// import" to ensure we generate a weak reference so the TSan dylib continues to +// work on older systems. We cannot simply #include or use the +// Darwin availability macros since this file is multi-platform. +SANITIZER_WEAK_IMPORT void dispatch_async_and_wait( + dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block); +SANITIZER_WEAK_IMPORT void dispatch_async_and_wait_f( + dispatch_queue_t queue, void *context, dispatch_function_t work); + DISPATCH_INTERCEPT_SYNC_B(dispatch_async_and_wait, false) +DISPATCH_INTERCEPT_SYNC_F(dispatch_async_and_wait_f, false) + DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when, dispatch_queue_t queue, void *context, dispatch_function_t work)