[compiler-rt] [compiler-rt] Handle weak interfaces with MinGW GCC (PR #222706)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 09:47:58 PDT 2026
https://github.com/oltolm created https://github.com/llvm/llvm-project/pull/222706
Windows weak-function emulation uses MSVC linker /alternatename directives, which GNU ld does not support. Use direct exported definitions, avoid registering unsupported DLL weak aliases, and reference UBSan's real C++ implementation.
>From e68e1e10bea2ca45b9f0dbe15bf4b7b35c144e7b Mon Sep 17 00:00:00 2001
From: Oleg Tolmatcev <oleg.tolmatcev at gmail.com>
Date: Thu, 10 Sep 2026 17:54:40 +0200
Subject: [PATCH] [compiler-rt] Handle weak interfaces with MinGW GCC
Windows weak-function emulation uses MSVC linker /alternatename
directives, which GNU ld does not support. Use direct exported
definitions, avoid registering unsupported DLL weak aliases, and
reference UBSan's real C++ implementation.
Co-authored-by: Hannes Domani <ssbssa at yahoo.de>
---
.../sanitizer_internal_defs.h | 8 ++--
.../sanitizer_win_thunk_interception.h | 41 +++++++++++--------
compiler-rt/lib/ubsan/ubsan_handlers.cpp | 7 +++-
3 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
index c694897b6556b..75980867d545d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -63,10 +63,10 @@
// For example:
// SANITIZER_INTERFACE_WEAK_DEF(bool, compare, int a, int b) { return a > b; }
//
-#if SANITIZER_WINDOWS
-#include "sanitizer_win_defs.h"
-# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
- WIN_WEAK_EXPORT_DEF(ReturnType, Name, __VA_ARGS__)
+#if SANITIZER_WINDOWS && (!defined(__GNUC__) || defined(__clang__))
+# include "sanitizer_win_defs.h"
+# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
+ WIN_WEAK_EXPORT_DEF(ReturnType, Name, __VA_ARGS__)
#else
# define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
index 4beaab5f15b93..492ef6b2b98b2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
@@ -69,21 +69,28 @@ void initialize_thunks(const sanitizer_thunk *begin,
# define REGISTER_WEAK_FUNCTION_ADDRESS(fn) &fn
#endif
-#define REGISTER_WEAK_FUNCTION(local_function) \
- extern "C" void local_function(); \
- extern "C" void WEAK_EXPORT_NAME(local_function)(); \
- WIN_WEAK_IMPORT_DEF(local_function) \
- REGISTER_WEAK_OPTNONE static int register_weak_##local_function() { \
- if ((uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS(local_function) != \
- (uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS( \
- WEAK_EXPORT_NAME(local_function))) { \
- return __sanitizer::register_weak( \
- SANITIZER_STRINGIFY(WEAK_EXPORT_NAME(local_function)), \
- reinterpret_cast<__sanitizer::uptr>(local_function)); \
- } \
- return 0; \
- } \
- __pragma(section(".WEAK$M", long, read)) __declspec(allocate( \
- ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
- register_weak_##local_function;
+#if !defined(__GNUC__) || defined(__clang__)
+# define REGISTER_WEAK_FUNCTION(local_function) \
+ extern "C" void local_function(); \
+ extern "C" void WEAK_EXPORT_NAME(local_function)(); \
+ WIN_WEAK_IMPORT_DEF(local_function) \
+ REGISTER_WEAK_OPTNONE static int register_weak_##local_function() { \
+ if ((uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS(local_function) != \
+ (uintptr_t)REGISTER_WEAK_FUNCTION_ADDRESS( \
+ WEAK_EXPORT_NAME(local_function))) { \
+ return __sanitizer::register_weak( \
+ SANITIZER_STRINGIFY(WEAK_EXPORT_NAME(local_function)), \
+ reinterpret_cast<__sanitizer::uptr>(local_function)); \
+ } \
+ return 0; \
+ } \
+ __pragma(section(".WEAK$M", long, read)) __declspec(allocate( \
+ ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
+ register_weak_##local_function;
+#else
+// GNU ld does not support /alternatename. User overrides of weak sanitizer
+// functions are not forwarded to the sanitizer DLL on this toolchain.
+# define REGISTER_WEAK_FUNCTION(local_function) \
+ extern "C" void local_function();
+#endif
#endif // SANITIZER_WIN_THUNK_INTERCEPTION_H
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cpp b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
index 0cd8a437adf4d..af207ee6ccccf 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -935,7 +935,7 @@ static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
namespace __ubsan {
-#ifdef _WIN32
+#if defined(_WIN32) && (!defined(__GNUC__) || defined(__clang__))
extern "C" void __ubsan_handle_cfi_bad_type_default(CFICheckFailData *Data,
ValueHandle Vtable,
bool ValidVtable,
@@ -944,6 +944,11 @@ extern "C" void __ubsan_handle_cfi_bad_type_default(CFICheckFailData *Data,
}
WIN_WEAK_ALIAS(__ubsan_handle_cfi_bad_type, __ubsan_handle_cfi_bad_type_default)
+void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
+ bool ValidVtable, ReportOptions Opts);
+#elif defined(_WIN32)
+// GNU ld does not support /alternatename. The real implementation lives in
+// ubsan_handlers_cxx.cpp.
void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
bool ValidVtable, ReportOptions Opts);
#else
More information about the llvm-commits
mailing list