The address of a thread local is technically constant however its value isn't known until the thread of execution starts, so constructing a GlobalVariable containing its address doesn't make sense unless it is also thread local and initialised at thread startup. LLVM doesn't appear to have a concept of TLS init like it does for static construction and destruction (ie something similar to llvm::appendToGlobal{C,D}tors() but for TLS) and clang's TLS init code isn't available down in LLVM, so this patch takes the easy option and avoids the issue altogether by rejecting values that are thread locals.
A better demonstration of where this code breaks is with:
#include <cstdio> thread_local int global_var; __attribute__((noinline)) void test_func(int*(&ptrs)[2]) { printf("&global_var = %p\n", &global_var); for (auto& p : ptrs) p = &global_var; } int main() { int*test[2]{}; test_func(test); printf("test[0] = %p\n", test[0]); }
which, on platforms that support memset_pattern16() and with optimisations enabled, will print something like:
&global_var = 0x7f1e51f77f3c test[0] = 0x403de0
where any reads/writes of *test[0] would indeed crash at the mysterious address 0x403de0.
What about GlobalVariable's that aren't global constants?