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
