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

Reply via email to