Author: Aaron Ballman
Date: 2025-05-19T11:28:48-04:00
New Revision: 7cf2860cbdc158a04d4a982fa7043cd9e6401e77

URL: 
https://github.com/llvm/llvm-project/commit/7cf2860cbdc158a04d4a982fa7043cd9e6401e77
DIFF: 
https://github.com/llvm/llvm-project/commit/7cf2860cbdc158a04d4a982fa7043cd9e6401e77.diff

LOG: [C++] Fix a crash with __thread and dependent types (#140542)

We were checking whether the initializer is a valid constant expression
even if the variable was dependent. Now we delay that checking until
after the template has been instantiated.

Fixes #140509

Added: 
    clang/test/SemaCXX/thread-specifier.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4a3c1bee82831..472b70b46fcc0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -558,6 +558,9 @@ Improvements to Clang's diagnostics
   between 
diff erent Unicode character types (``char8_t``, ``char16_t``, ``char32_t``).
   This warning only triggers in C++ as these types are aliases in C. 
(#GH138526)
 
+- Fixed a crash when checking a ``__thread``-specified variable declaration
+  with a dependent type in C++. (#GH140509)
+
 Improvements to Clang's time-trace
 ----------------------------------
 

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d47c1d39adf92..ad0e274d02ef5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14608,6 +14608,10 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl 
*var) {
   std::optional<bool> CacheHasConstInit;
   const Expr *CacheCulprit = nullptr;
   auto checkConstInit = [&]() mutable {
+    const Expr *Init = var->getInit();
+    if (Init->isInstantiationDependent())
+      return true;
+
     if (!CacheHasConstInit)
       CacheHasConstInit = var->getInit()->isConstantInitializer(
             Context, var->getType()->isReferenceType(), &CacheCulprit);

diff  --git a/clang/test/SemaCXX/thread-specifier.cpp 
b/clang/test/SemaCXX/thread-specifier.cpp
new file mode 100644
index 0000000000000..2b909ecd175d0
--- /dev/null
+++ b/clang/test/SemaCXX/thread-specifier.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++23 -verify %s
+
+namespace GH140509 {
+template <typename T>
+void not_instantiated() {
+  static __thread T my_wrapper;
+}
+
+template <typename T>
+void instantiated() {
+  static __thread T my_wrapper = T{}; // expected-error {{initializer for 
thread-local variable must be a constant expression}} \
+                                         expected-note {{use 'thread_local' to 
allow this}}
+}
+
+template <typename T>
+void nondependent_var() {
+  // Verify that the dependence of the initializer is what really matters.
+  static __thread int my_wrapper = T{};
+}
+
+struct S {
+  S() {}
+};
+
+void f() {
+  instantiated<int>();
+  instantiated<S>(); // expected-note {{in instantiation of function template 
specialization 'GH140509::instantiated<GH140509::S>' requested here}}
+  nondependent_var<int>();
+}
+} // namespace GH140509


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to