[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:48:43 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: oltolm (oltolm)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/222706.diff


3 Files Affected:

- (modified) compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h (+4-4) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h (+24-17) 
- (modified) compiler-rt/lib/ubsan/ubsan_handlers.cpp (+6-1) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/222706


More information about the llvm-commits mailing list