[clang] [CIR] Fix 'vague' linkage globals. (PR #228586)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 7 08:50:20 PDT 2026


================
@@ -1262,6 +1277,26 @@ LoweringPreparePass::buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op) {
   // If this is a global TLS variable (that is, declared at namespace scope), we
   // have to emit the guard variable here.
   bool needsTlsGuard = op.getTlsRefs() && op.getTlsRefs()->getGuardName();
+
+  // Non-TLS globals (such as weak/linkonce_odr/inline-ns scope variables) use
+  // the __cxa_guard_acquire/release instead of the TLS guard.
+  if (!needsTlsGuard && op.getDynamicInitGuard()) {
+    if (!op.getDynamicInitInfo()) {
+      op->emitError(
+          "guarded global with a guard is missing 'dynamic_init_info'");
+      return {};
+    }
+
+    if (op.getDynamicInitInfo()->getLocal()) {
+      op->emitError("guarded global is marked local");
+      return {};
+    }
+    emitGuardedInit(builder, op, op.getCtorRegion(), op.getDtorRegion());
----------------
erichkeane wrote:

This took AGES to find something that caused a problem here! I considered just adding max-blocks to GlobalOp, which seemed fine (and the test added that resulted in it being AnyRegion didn't repro the issue!).

You have to do some pretty awful things to the language in order to make multiple blocks.

However, the work to make sure we properly copy those/etc for some pretty obnoxious reproducers caused me to think that setting GlobalOp to just use MaxRegions as well is the right idea.  I had to do some minor work in CIRGenCXX to 'wrap' multiple blocks in 1 region, but that seemed like the lesser of 2 evils here.  

You're really hitting me hard here :D

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


More information about the cfe-commits mailing list