https://github.com/dty2 updated https://github.com/llvm/llvm-project/pull/138122
>From a36e3e758221afd97626819e00772ac1e132d927 Mon Sep 17 00:00:00 2001 From: hunter <284050...@qq.com> Date: Thu, 1 May 2025 18:52:34 +0800 Subject: [PATCH] [Clang] Fix missed initializer instantiation bug for variable templates [Clang] Fix missed initializer instantiation bug for variable templates --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 +++--- .../test/CodeGenCXX/cxx1z-inline-variables.cpp | 14 ++++++++++++++ .../SemaTemplate/cxx17-inline-variables.cpp | 12 ++++++++++++ clang/tools/driver/driver.cpp | 18 +++++++++--------- 5 files changed, 39 insertions(+), 12 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..1cb30b178e06f 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 inlineauto = 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 partialinlineauto = 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..06f1ec17fb7a8 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 inlineauto = InlineAuto<int>::var<int>; +int partialinlineauto = PartialInlineAuto<int>::var<int, int>; diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 82f47ab973064..d7d3b0942663b 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -72,7 +72,7 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { // This just needs to be some symbol in the binary; C++ doesn't // allow taking the address of ::main however. - void *P = (void*) (intptr_t) GetExecutablePath; + void *P = (void *)(intptr_t)GetExecutablePath; return llvm::sys::fs::getMainExecutable(Argv0, P); } @@ -105,10 +105,10 @@ static void insertTargetAndModeArgs(const ParsedClangName &NameParts, } if (NameParts.TargetIsValid) { - const char *arr[] = {"-target", GetStableCStr(SavedStrings, - NameParts.TargetPrefix)}; - ArgVector.insert(ArgVector.begin() + InsertionPoint, - std::begin(arr), std::end(arr)); + const char *arr[] = {"-target", + GetStableCStr(SavedStrings, NameParts.TargetPrefix)}; + ArgVector.insert(ArgVector.begin() + InsertionPoint, std::begin(arr), + std::end(arr)); } } @@ -328,8 +328,8 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { // actions. DiagOpts->DiagnosticSuppressionMappingsFile.clear(); - TextDiagnosticPrinter *DiagClient - = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); + TextDiagnosticPrinter *DiagClient = + new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); FixupDiagPrefixExeName(DiagClient, ProgName); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); @@ -439,8 +439,8 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) llvm::dbgs() << llvm::getBugReportMsg(); if (FailingCommand != nullptr && - TheDriver.maybeGenerateCompilationDiagnostics(CommandStatus, ReproLevel, - *C, *FailingCommand)) + TheDriver.maybeGenerateCompilationDiagnostics(CommandStatus, ReproLevel, + *C, *FailingCommand)) Res = 1; Diags.getClient()->finish(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits