[llvm] [Support][Windows] Add utility function for retrieving a DLL-exported function (PR #97905)

Alexandre Ganea via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 6 09:33:18 PDT 2024


https://github.com/aganea created https://github.com/llvm/llvm-project/pull/97905

Since functions exported from DLLs are type-erased, before this patch I was seeing the new Clang 19 warning `-Wcast-function-type-mismatch`.

This happens when building LLVM on Windows.

>From ea06f09573b7cf9b7899b78439f29b0f94fcc030 Mon Sep 17 00:00:00 2001
From: Alexandre Ganea <aganea at havenstudios.com>
Date: Sat, 6 Jul 2024 12:29:41 -0400
Subject: [PATCH] [Support][Windows] Add utility function for retrieving a
 DLL-exported function

Since functions exported from DLLs are type-erased, before this patch I
was seeing the new Clang 19 warning `-Wcast-function-type-mismatch`.

This happens when building LLVM on Windows.
---
 .../llvm/Support/Windows/WindowsSupport.h     |  6 +++++
 llvm/lib/Support/Windows/Process.inc          |  3 ++-
 llvm/lib/Support/Windows/Signals.inc          | 22 ++++++++++---------
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
index d3aacd14b2097..1f4bd71aec49f 100644
--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
+++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
@@ -245,6 +245,12 @@ std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
 std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
                           size_t MaxPathLen = MAX_PATH);
 
+/// Dynamically retrieve an exported function from a DLL, while casting it to a
+/// known type. This avoids -Wcast-function-type-mismatch.
+template <typename T> T funcFromModule(HMODULE Mod, StringRef Name) {
+  return (T)(void *)::GetProcAddress(Mod, Name.data());
+}
+
 } // end namespace windows
 } // end namespace sys
 } // end namespace llvm.
diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc
index 34d294b232c32..4f6a41e23904e 100644
--- a/llvm/lib/Support/Windows/Process.inc
+++ b/llvm/lib/Support/Windows/Process.inc
@@ -482,7 +482,8 @@ static RTL_OSVERSIONINFOEXW GetWindowsVer() {
     HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
     assert(hMod);
 
-    auto getVer = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
+    auto getVer = llvm::sys::windows::funcFromModule<RtlGetVersionPtr>(
+        hMod, "RtlGetVersion");
     assert(getVer);
 
     RTL_OSVERSIONINFOEXW info{};
diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc
index 29ebf7c696e04..432b2e9b8dfd7 100644
--- a/llvm/lib/Support/Windows/Signals.inc
+++ b/llvm/lib/Support/Windows/Signals.inc
@@ -168,25 +168,27 @@ static bool isDebugHelpInitialized() {
 }
 
 static bool load64BitDebugHelp(void) {
+  using namespace llvm::sys::windows;
+
   HMODULE hLib =
       ::LoadLibraryExA("Dbghelp.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
   if (hLib) {
     fMiniDumpWriteDump =
-        (fpMiniDumpWriteDump)::GetProcAddress(hLib, "MiniDumpWriteDump");
-    fStackWalk64 = (fpStackWalk64)::GetProcAddress(hLib, "StackWalk64");
+        funcFromModule<fpMiniDumpWriteDump>(hLib, "MiniDumpWriteDump");
+    fStackWalk64 = funcFromModule<fpStackWalk64>(hLib, "StackWalk64");
     fSymGetModuleBase64 =
-        (fpSymGetModuleBase64)::GetProcAddress(hLib, "SymGetModuleBase64");
+        funcFromModule<fpSymGetModuleBase64>(hLib, "SymGetModuleBase64");
     fSymGetSymFromAddr64 =
-        (fpSymGetSymFromAddr64)::GetProcAddress(hLib, "SymGetSymFromAddr64");
+        funcFromModule<fpSymGetSymFromAddr64>(hLib, "SymGetSymFromAddr64");
     fSymGetLineFromAddr64 =
-        (fpSymGetLineFromAddr64)::GetProcAddress(hLib, "SymGetLineFromAddr64");
+        funcFromModule<fpSymGetLineFromAddr64>(hLib, "SymGetLineFromAddr64");
     fSymGetModuleInfo64 =
-        (fpSymGetModuleInfo64)::GetProcAddress(hLib, "SymGetModuleInfo64");
-    fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)::GetProcAddress(
+        funcFromModule<fpSymGetModuleInfo64>(hLib, "SymGetModuleInfo64");
+    fSymFunctionTableAccess64 = funcFromModule<fpSymFunctionTableAccess64>(
         hLib, "SymFunctionTableAccess64");
-    fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions");
-    fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize");
-    fEnumerateLoadedModules = (fpEnumerateLoadedModules)::GetProcAddress(
+    fSymSetOptions = funcFromModule<fpSymSetOptions>(hLib, "SymSetOptions");
+    fSymInitialize = funcFromModule<fpSymInitialize>(hLib, "SymInitialize");
+    fEnumerateLoadedModules = funcFromModule<fpEnumerateLoadedModules>(
         hLib, "EnumerateLoadedModules64");
   }
   return isDebugHelpInitialized();



More information about the llvm-commits mailing list