llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

We were using AssumedTemplate incorrectly for error recovery.

Fixes #<!-- -->135621

---
Full diff: https://github.com/llvm/llvm-project/pull/135893.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2-1) 
- (modified) clang/lib/AST/Type.cpp (+2-1) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+7-4) 
- (modified) clang/test/SemaTemplate/recovery-crash.cpp (+11) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 38142ad32bea0..562ac29f4b998 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. (#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..5d9fd78c52968 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -21111,11 +21111,14 @@ 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: Can't qualify an assumed template because it explicitly models 
the
+    // unqualified-id case. Just dropping the qualifiers is wrong though.
+    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

``````````

</details>


https://github.com/llvm/llvm-project/pull/135893
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to