https://github.com/conrade-ctc created 
https://github.com/llvm/llvm-project/pull/207161

When emulated TLS is enabled, `IRMaterializationUnit`'s constructor emits an 
`__emutls_t.<var>` symbol for each non-zero-initialized `thread_local` global 
and records it in `SymbolFlags`, but never adds it to `SymbolToDefinition`.

If the same weak (`linkonce_odr`) definition is materialized by more than one 
module — e.g. an `inline` function that odr-uses such a `thread_local`, pulled 
into two `PartialTranslationUnit`s by clang-repl — `JITDylib::defineImpl` 
discards the duplicate via `IRMaterializationUnit::discard()`. `discard()` 
looks the symbol up in `SymbolToDefinition` and, finding nothing, dereferences 
`end()`: an assertion failure in `+Asserts` builds and heap corruption 
otherwise.

Register `__emutls_t.<var>` in `SymbolToDefinition` alongside its flags, 
mirroring the `__emutls_v.<var>` handling just above.

### Test

`clang/test/Interpreter/emulated-tls.cpp` reproduces the crash through 
clang-repl: two PTUs each odr-use one `inline worker()` that reads a non-zero 
`thread_local`, so each re-emits the same weak emulated-TLS set; defining the 
second module runs `discard()` over the duplicate. The test aborts on the 
unfixed path and prints the expected value with the fix.

🤖 Done with the help of [Claude Code](https://claude.com/claude-code) (Claude 
Opus 4.8, human in the loop)


>From 9bf13f8f2aa2771f1e07f068c66c08943f044d81 Mon Sep 17 00:00:00 2001
From: Emery Conrad <[email protected]>
Date: Thu, 2 Jul 2026 06:33:06 -0500
Subject: [PATCH] [ORC] Track __emutls_t definitions in IRMaterializationUnit

The emulated-TLS path registered __emutls_t.<var> in SymbolFlags but not
SymbolToDefinition, so discarding a duplicated weak TLS symbol dereferenced
end(). Add it, mirroring __emutls_v.<var>.

Co-developed-with-the-help-of: Claude Code (Claude Opus 4.8, human in the loop)
---
 clang/test/Interpreter/emulated-tls.cpp | 25 +++++++++++++++++++++++++
 llvm/lib/ExecutionEngine/Orc/Layer.cpp  |  1 +
 2 files changed, 26 insertions(+)
 create mode 100644 clang/test/Interpreter/emulated-tls.cpp

diff --git a/clang/test/Interpreter/emulated-tls.cpp 
b/clang/test/Interpreter/emulated-tls.cpp
new file mode 100644
index 0000000000000..73afe172ef6d9
--- /dev/null
+++ b/clang/test/Interpreter/emulated-tls.cpp
@@ -0,0 +1,25 @@
+// REQUIRES: host-supports-jit
+// UNSUPPORTED: system-windows
+//
+// An inline function that odr-uses a non-zero-initialized thread_local is
+// emitted as a weak (linkonce_odr) definition into every 
PartialTranslationUnit
+// that references it. With emulated TLS that set includes an __emutls_t.<var>
+// symbol. When a later PTU re-defines the same weak set, ORC's
+// IRMaterializationUnit::discard() must find each duplicated symbol in its
+// SymbolToDefinition map. The emulated-TLS path used to register 
__emutls_t.<var>
+// in SymbolFlags but not SymbolToDefinition, so discarding it dereferenced
+// end() -- an assertion failure in +Asserts builds and heap corruption
+// otherwise. Two PTUs each pulling in the same inline worker reproduces it.
+//
+// RUN: cat %s | clang-repl | FileCheck %s
+
+extern "C" int printf(const char *, ...);
+template <int Tag> struct HeavyThing { static thread_local int tls; };
+template <int Tag> thread_local int HeavyThing<Tag>::tls = Tag + 1;
+inline int worker() { return HeavyThing<1>::tls; }
+int callA() { return worker(); }
+int callB() { return worker(); }
+auto r = printf("tls = %d, %d\n", callA(), callB());
+// CHECK: tls = 2, 2
+
+%quit
diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp 
b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index eb144275da589..5e95b8c73b482 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -70,6 +70,7 @@ IRMaterializationUnit::IRMaterializationUnit(
 
           auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());
           SymbolFlags[EmuTLST] = Flags;
+          SymbolToDefinition[EmuTLST] = &GV;
         }
         continue;
       }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to