https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/135893
>From d06164cda2bccc398a49bbbfadb728184ff6cb73 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Tue, 15 Apr 2025 21:54:04 -0300 Subject: [PATCH] [clang] fix a crash in error recovery in expressions resolving to templates We were using AssumedTemplate incorrectly for error recovery. Fixes #135621 --- clang/docs/ReleaseNotes.rst | 3 ++- clang/lib/AST/Type.cpp | 3 ++- clang/lib/Sema/SemaExpr.cpp | 12 ++++++++---- clang/test/SemaTemplate/recovery-crash.cpp | 11 +++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 38142ad32bea0..b6fbfb12ef7f9 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -406,6 +406,7 @@ Bug Fixes in This Version when using the ``INTn_C`` macros. (#GH85995) - Fixed an assertion failure in the expansion of builtin macros like ``__has_embed()`` with line breaks before the closing paren. (#GH133574) +- Fixed a crash in error recovery for expressions resolving to templates. (#GH135621) - Clang no longer accepts invalid integer constants which are too large to fit into any (standard or extended) integer type when the constant is unevaluated. Merely forming the token is sufficient to render the program invalid. Code @@ -549,7 +550,7 @@ Arm and AArch64 Support ^^^^^^^^^^^^^^^^^^^^^^^ - For ARM targets, cc1as now considers the FPU's features for the selected CPU or Architecture. - The ``+nosimd`` attribute is now fully supported for ARM. Previously, this had no effect when being used with - ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is + ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is also now printed when the ``--print-supported-extensions`` option is used. - Support for __ptrauth type qualifier has been added. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 62e48062cf241..53620003c9655 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -4401,7 +4401,8 @@ TemplateSpecializationType::TemplateSpecializationType( T.getKind() == TemplateName::SubstTemplateTemplateParmPack || T.getKind() == TemplateName::UsingTemplate || T.getKind() == TemplateName::QualifiedTemplate || - T.getKind() == TemplateName::DeducedTemplate) && + T.getKind() == TemplateName::DeducedTemplate || + T.getKind() == TemplateName::AssumedTemplate) && "Unexpected template name for TemplateSpecializationType"); auto *TemplateArgs = diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3ac7d61546ceb..c65b4eadf9c67 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -21111,11 +21111,15 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { const bool IsTypeAliasTemplateDecl = isa<TypeAliasTemplateDecl>(Temp); NestedNameSpecifier *NNS = ULE->getQualifierLoc().getNestedNameSpecifier(); - TemplateName TN(dyn_cast<TemplateDecl>(Temp)); - if (TN.isNull()) + // FIXME: AssumedTemplate is not very appropriate for error recovery here, + // as it models only the unqualified-id case, where this case can clearly be + // qualified. Thus we can't just qualify an assumed template. + TemplateName TN; + if (auto *TD = dyn_cast<TemplateDecl>(Temp)) + TN = Context.getQualifiedTemplateName(NNS, ULE->hasTemplateKeyword(), + TemplateName(TD)); + else TN = Context.getAssumedTemplateName(NameInfo.getName()); - TN = Context.getQualifiedTemplateName(NNS, - /*TemplateKeyword=*/true, TN); Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template) << TN << ULE->getSourceRange() << IsTypeAliasTemplateDecl; diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp index ac8053da101ab..9b106f1f21fc5 100644 --- a/clang/test/SemaTemplate/recovery-crash.cpp +++ b/clang/test/SemaTemplate/recovery-crash.cpp @@ -67,3 +67,14 @@ namespace test1 { // expected-note@#defined-here {{defined here}} void NonTemplateClass::UndeclaredMethod() {} } + +namespace GH135621 { + template <class T> struct S {}; + // expected-note@-1 {{class template declared here}} + template <class T2> void f() { + S<T2>::template S<int>; + // expected-error@-1 {{'S' is expected to be a non-type template, but instantiated to a class template}} + } + template void f<int>(); + // expected-note@-1 {{requested here}} +} // namespace GH135621 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits