[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