[llvm] [Offload] Fix -Wglobal-constructors for State.cpp mutex on Windows (PR #216259)

Wenju He via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 23:42:06 PDT 2026


https://github.com/wenju-he created https://github.com/llvm/llvm-project/pull/216259

MSVC STL's std::mutex has a non-trivial default constructor, so the file-scope StateLock and ThreadStatesLock globals emit a dynamic initializer and trigger -Werror=global-constructors on Windows build.

>From d1a0fcdd4f4a9426b9b3426894c9fc18920e5d5d Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Fri, 14 Aug 2026 08:41:26 +0200
Subject: [PATCH] [Offload] Fix -Wglobal-constructors for State.cpp mutex on
 Windows

MSVC STL's std::mutex has a non-trivial default constructor, so the
file-scope StateLock and ThreadStatesLock globals emit a dynamic
initializer and trigger -Werror=global-constructors on Windows build.

Co-Authored-By: Claude Sonnet 5 <noreply at anthropic.com>
---
 offload/languages/kernel/src/State.cpp | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/offload/languages/kernel/src/State.cpp b/offload/languages/kernel/src/State.cpp
index da4de0d5da8d4..49739022321fd 100644
--- a/offload/languages/kernel/src/State.cpp
+++ b/offload/languages/kernel/src/State.cpp
@@ -27,19 +27,25 @@ using namespace offload;
 __attribute__((weak)) uint32_t PerThreadQueue = 0;
 
 // Process-wide singleton and thread-state registry.
-static std::mutex StateLock;
+static std::mutex &getStateLock() {
+  static std::mutex StateLock;
+  return StateLock;
+}
 static std::atomic<StateTy *> StatePtr = nullptr;
 
 static thread_local ThreadStateTy *ThreadState = nullptr;
 
-static std::mutex ThreadStatesLock;
+static std::mutex &getThreadStatesLock() {
+  static std::mutex ThreadStatesLock;
+  return ThreadStatesLock;
+}
 using ThreadStatesTy = SmallVector<ThreadStateTy *, 64>;
 static ThreadStatesTy *ThreadStatesPtr = nullptr;
 
 static void deleteThreadStates() {
   // Detach the registry before deletion because deleteThreadState may be called
   // more than once via atexit and StateTy teardown.
-  std::lock_guard<std::mutex> LG(ThreadStatesLock);
+  std::lock_guard<std::mutex> LG(getThreadStatesLock());
   ThreadStatesTy *ThreadStates = ThreadStatesPtr;
   ThreadStatesPtr = nullptr;
   if (!ThreadStates)
@@ -84,7 +90,7 @@ ThreadStateTy &ThreadStateTy::get() {
   auto *&TS = ThreadState;
   if (!TS) {
     TS = new ThreadStateTy();
-    std::lock_guard<std::mutex> LG(ThreadStatesLock);
+    std::lock_guard<std::mutex> LG(getThreadStatesLock());
     if (!ThreadStatesPtr)
       ThreadStatesPtr = new ThreadStatesTy;
     ThreadStatesPtr->push_back(TS);
@@ -134,7 +140,7 @@ void ThreadStateTy::createDefaultQueue(ol_device_handle_t Device) {
 StateTy &StateTy::get() {
   StateTy *ST = StatePtr.load();
   if (!ST) [[unlikely]] {
-    std::lock_guard<std::mutex> LG(StateLock);
+    std::lock_guard<std::mutex> LG(getStateLock());
     ST = StatePtr.load();
     if (!ST) {
       ST = new StateTy();



More information about the llvm-commits mailing list