[clang] Fix missing initializer for inline static template member with auto caused by delayed template instantiation. (PR #138122)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 1 05:04:56 PDT 2025


https://github.com/dty2 updated https://github.com/llvm/llvm-project/pull/138122

>From f9bdf07f09d7a04c190ae4d77c4983d4b7fa4936 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Thu, 1 May 2025 18:52:34 +0800
Subject: [PATCH 1/2] [clang] Fix missing initializer for inline static
 template member with auto caused by delayed template instantiation.

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp     | 8 +++++++-
 clang/test/CodeGenCXX/cxx1z-inline-variables.cpp   | 8 ++++++++
 clang/test/SemaTemplate/cxx17-inline-variables.cpp | 6 ++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 76c055d28f091..eb66ec34a956f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6027,8 +6027,14 @@ void Sema::BuildVariableInstantiation(
   Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
   Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
 
+  bool VarTemplateWithAutoType = false;
+  QualType VarSourceType = OldVar->getTypeSourceInfo()->getType();
+  if (VarSourceType->getAs<AutoType>()) {
+    VarTemplateWithAutoType = true;
+  }
+
   // Figure out whether to eagerly instantiate the initializer.
-  if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {
+  if ((InstantiatingVarTemplate && !VarTemplateWithAutoType) || InstantiatingVarTemplatePartialSpec) {
     // We're producing a template. Don't instantiate the initializer yet.
   } else if (NewVar->getType()->isUndeducedType()) {
     // We need the type to complete the declaration of the variable.
diff --git a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
index 812e438f30c9a..b1d8e376b826f 100644
--- a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
+++ b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -1,5 +1,13 @@
 // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
 
+template <typename T> struct B {
+  template <typename G> inline static auto var = 5;
+};
+
+int inlinevartemplate = B<int>::var<int>;
+// CHECK: @_ZN1BIiE3varIiEE = {{.*}}global i32 5{{.*}}comdat
+// CHECK-NOT: @_ZN1BIiE3varIfEE
+
 struct Q {
   // CHECK: @_ZN1Q1kE = linkonce_odr constant i32 5, comdat
   static constexpr int k = 5;
diff --git a/clang/test/SemaTemplate/cxx17-inline-variables.cpp b/clang/test/SemaTemplate/cxx17-inline-variables.cpp
index 7fc0aa8eeeb0c..27067c8e1b5e4 100644
--- a/clang/test/SemaTemplate/cxx17-inline-variables.cpp
+++ b/clang/test/SemaTemplate/cxx17-inline-variables.cpp
@@ -27,3 +27,9 @@ template <typename T> constexpr int A<T>::n = sizeof(A) + sizeof(T);
 template <typename T> inline constexpr int A<T>::m = sizeof(A) + sizeof(T);
 static_assert(A<int>().f() == 5);
 static_assert(A<int>().g() == 5);
+
+template <typename T> struct B {
+  template <typename G> inline static auto var = 5;
+};
+
+int b = B<int>::var<int>;

>From 3c21bee1e8336bbcecab8e94f82ba3ee8aa3fddd Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Thu, 1 May 2025 20:02:38 +0800
Subject: [PATCH 2/2] [Clang] Fix missing initializer for inline static
 template member with auto caused by delayed template instantiation.

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index eb66ec34a956f..c0a0feda6824d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6034,7 +6034,8 @@ void Sema::BuildVariableInstantiation(
   }
 
   // Figure out whether to eagerly instantiate the initializer.
-  if ((InstantiatingVarTemplate && !VarTemplateWithAutoType) || InstantiatingVarTemplatePartialSpec) {
+  if ((InstantiatingVarTemplate && !VarTemplateWithAutoType) ||
+      InstantiatingVarTemplatePartialSpec) {
     // We're producing a template. Don't instantiate the initializer yet.
   } else if (NewVar->getType()->isUndeducedType()) {
     // We need the type to complete the declaration of the variable.



More information about the cfe-commits mailing list