When an odr-use of a constinit thread_local variable of incomplete class type occurs, Clang does not make any attempt to register the odr-use (and thus the initialization and any associated destructor calls). The case where the variable is a (possibly multi-dimensional) array of an incomplete class type is similarly affected. ### SOURCE (<stdin>): struct A; extern constinit thread_local A a; A &foo() { return a; } ### COMPILER INVOCATION: clang -cc1 -emit-llvm -Wall -Wextra -Werror -pedantic-errors -std=c++20 -xc++ -std=c++20 - ### ACTUAL OUTPUT (IR snippet): define dso_local nonnull align 1 %struct.A* @_Z3foov() #0 { entry: ret %struct.A* @a } ### EXPECTED OUTPUT (IR snippet): define dso_local nonnull align 1 dereferenceable(1) %struct.A* @_Z3foov() #0 { entry: %0 = call %struct.A* @_ZTW1a() ret %struct.A* %0 } ### COMPILER VERSION INFO (clang++ -v): clang version 13.0.0 (https://github.com/llvm/llvm-project.git c4ed142e695f14ba5675ec6d12226ee706329a0f) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /opt/wandbox/clang-head/bin Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.5.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.5.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.5.0 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Candidate multilib: x32;@mx32 Selected multilib: .;@m64
We were incorrectly assuming incomplete class types were trivially destructible.