https://github.com/zwuis created https://github.com/llvm/llvm-project/pull/134522
Fixes #51347 >From ccab3dc1f18ffeda9acb07c0bd5f80f65cc788b9 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <zw...@outlook.com> Date: Sun, 6 Apr 2025 15:06:56 +0800 Subject: [PATCH] Handle invalid variable template specialization whose type depends on itself --- clang/docs/ReleaseNotes.rst | 2 ++ .../include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaTemplate.cpp | 7 +++++++ .../SemaTemplate/instantiate-var-template.cpp | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5217e04b5e83f..9e0fe8a94729b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -414,6 +414,8 @@ 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) +- No longer crashes when instantiating invalid variable template specialization + whose type depends on itself. (#GH51347) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 393bfecf9a36b..0c1da40dba388 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5259,6 +5259,9 @@ def err_template_member_noparams : Error< "extraneous 'template<>' in declaration of member %0">; def err_template_tag_noparams : Error< "extraneous 'template<>' in declaration of %0 %1">; +def err_var_template_spec_type_depends_on_self : Error< + "the type of variable template specialization %0 declared with deduced type " + "%1 depends on itself">; def warn_unqualified_call_to_std_cast_function : Warning< "unqualified call to '%0'">, InGroup<DiagGroup<"unqualified-std-cast-call">>; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 153f44f8ec67a..ce54dbbb3b9fe 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4377,6 +4377,13 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, if (VarTemplateSpecializationDecl *Spec = Template->findSpecialization(CTAI.CanonicalConverted, InsertPos)) { checkSpecializationReachability(TemplateNameLoc, Spec); + if (Spec->getType()->isUndeducedType()) { + // We are substituting the initializer of this variable template + // specialization. + Diag(TemplateNameLoc, diag::err_var_template_spec_type_depends_on_self) + << Spec << Spec->getType(); + return true; + } // If we already have a variable template specialization, return it. return Spec; } diff --git a/clang/test/SemaTemplate/instantiate-var-template.cpp b/clang/test/SemaTemplate/instantiate-var-template.cpp index 60d3bd3b59f53..34a1b9710814b 100644 --- a/clang/test/SemaTemplate/instantiate-var-template.cpp +++ b/clang/test/SemaTemplate/instantiate-var-template.cpp @@ -47,3 +47,21 @@ namespace InvalidInsertPos { template<> int v<int, 0>; int k = v<int, 500>; } + +namespace GH51347 { + template <typename T> + auto p = p<T>; // expected-error {{the type of variable template specialization 'p<int>'}} + + auto x = p<int>; // expected-note {{in instantiation of variable template specialization 'GH51347::p'}} +} + +namespace GH97881_comment { + template <bool B> + auto g = sizeof(g<!B>); + // expected-error@-1 {{the type of variable template specialization 'g<false>'}} + // expected-note@-2 {{in instantiation of variable template specialization 'GH97881_comment::g'}} + + void test() { + (void)sizeof(g<false>); // expected-note {{in instantiation of variable template specialization 'GH97881_comment::g'}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits