[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 8 23:31:20 PDT 2025
https://github.com/dty2 updated https://github.com/llvm/llvm-project/pull/138122
>From 659cebc431e22e782454de02a1f05545e645659d Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Thu, 1 May 2025 18:52:34 +0800
Subject: [PATCH] [clang] Fix missing initializer for inline static template
member with auto caused by delayed template instantiation.
[Clang] Fix missing initializer for inline static template member with auto caused by delayed template instantiation.
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 +++---
clang/test/CodeGenCXX/cxx1z-inline-variables.cpp | 14 ++++++++++++++
clang/test/SemaTemplate/cxx17-inline-variables.cpp | 12 ++++++++++++
4 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ba6e40f145655..1fb0d8b80a7d4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -604,6 +604,7 @@ Bug Fixes to C++ Support
- Clang now issues an error when placement new is used to modify a const-qualified variable
in a ``constexpr`` function. (#GH131432)
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
+- Fix missing initializer for inline static template member with auto type caused by delayed template instantiation. (#GH138122)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 76c055d28f091..baac0b8e47c90 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6028,11 +6028,11 @@ void Sema::BuildVariableInstantiation(
Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
// Figure out whether to eagerly instantiate the initializer.
- if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {
- // We're producing a template. Don't instantiate the initializer yet.
- } else if (NewVar->getType()->isUndeducedType()) {
+ if (NewVar->getType()->isUndeducedType()) {
// We need the type to complete the declaration of the variable.
InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
+ } else if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {
+ // We're producing a template. Don't instantiate the initializer yet.
} else if (InstantiatingSpecFromTemplate ||
(OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
!NewVar->isThisDeclarationADefinition())) {
diff --git a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
index 812e438f30c9a..88d508c511497 100644
--- a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
+++ b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -1,5 +1,19 @@
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
+template <typename T> struct InlineAuto {
+ template <typename G> inline static auto var = 5;
+};
+int inlineauot = InlineAuto<int>::var<int>;
+// CHECK: @_ZN10InlineAutoIiE3varIiEE = {{.*}}i32 5{{.*}}comdat
+//
+template <typename> struct PartialInlineAuto {
+ template <typename, typename> inline static auto var = 6;
+ template <typename T> inline static auto var<int, T> = 7;
+};
+
+int partialinlineauot = PartialInlineAuto<int>::var<int, int>;
+// CHECK: @_ZN17PartialInlineAutoIiE3varIiiEE = {{.*}}i32 7{{.*}}comdat
+
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..bac18e489ca8d 100644
--- a/clang/test/SemaTemplate/cxx17-inline-variables.cpp
+++ b/clang/test/SemaTemplate/cxx17-inline-variables.cpp
@@ -27,3 +27,15 @@ 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 InlineAuto {
+ template <typename G> inline static auto var = 5;
+};
+
+template <typename> struct PartialInlineAuto {
+ template <typename, typename> inline static auto var = 6;
+ template <typename T> inline static auto var<int, T> = 7;
+};
+
+int inlineauot = InlineAuto<int>::var<int>;
+int partialinlineauot = PartialInlineAuto<int>::var<int, int>;
More information about the cfe-commits
mailing list