https://github.com/Dash198 created 
https://github.com/llvm/llvm-project/pull/235456

This PR builds on the approach explored in #142278  to address incorrect error 
recovery when a class definition appears within an alias template.

Fixes #91564   

Initial attempt to change the underlying type of the invalid 
`TemplateTypeParmDecl` to `int` triggered an assertion as template type 
parameter declarations are expected to retain their `TemplateTypeParmType` 
representation.

Instead, the declarations in the template-parameter scope are invalidated when 
the invalid class definition parsing begins and then any subsequent references 
to the invalid template type parameters are recovered as `int` explicitly in 
`Sema::getTypeName`.

Note on AI assistance: An LLM was used to help diagnose the crash encountered 
during the initial approach, understand the relevant Clang codebase, and trace 
the source files and code paths involved in the issue.

>From b47f903709c2f400ee09bdaf505d349b638cce2b Mon Sep 17 00:00:00 2001
From: Dash198 <[email protected]>
Date: Sun, 25 Oct 2026 19:33:41 +0530
Subject: [PATCH] [Clang] Improve error recovery for invalid alias templates

---
 clang/lib/Sema/SemaDecl.cpp                   | 19 ++++++++++++++++++-
 .../SemaCXX/concept-crash-on-diagnostic.cpp   | 15 +++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6aae0b57df0f99..037a74af032755 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -544,11 +544,18 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, 
SourceLocation NameLoc,
           SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
           NameLoc);
     } else {
-      T = Context.getTypeDeclType(TD);
+      // For invalid TTP mark them as integers to avoid incorrect error 
recovery
+      if(auto *TTP = dyn_cast<TemplateTypeParmDecl>(TD);
+          TTP && TTP->isInvalidDecl())
+        T = Context.IntTy;
+      else
+        T = Context.getTypeDeclType(TD);
       if (!WantNontrivialTypeSourceInfo)
         return ParsedType::make(T);
       if (isa<ObjCTypeParamType>(T))
         TLB.push<ObjCTypeParamTypeLoc>(T).setNameLoc(NameLoc);
+      else if (T->isBuiltinType())
+        TLB.pushTrivial(Context, T, NameLoc);
       else
         TLB.pushTypeSpec(T).setNameLoc(NameLoc);
     }
@@ -19324,6 +19331,16 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl 
*TagD) {
   AdjustDeclIfTemplate(TagD);
   TagDecl *Tag = cast<TagDecl>(TagD);
 
+  // If class is defined within the alias template then mark the parameters of
+  // the template as invalid first to avoid incorrect error recovery.
+  if (Scope *Parent = S->getParent();
+      Parent && Parent->isTypeAliasScope() &&
+      Parent->isTemplateParamScope()){
+    for (Decl *D : Parent->decls()){
+      D->setInvalidDecl();
+    }
+  }
+
   // Enter the tag context.
   PushDeclContext(S, Tag);
 
diff --git a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp 
b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
index a021267b45d2fe..1083adaf1ca480 100644
--- a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
+++ b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
@@ -86,3 +86,18 @@ static_assert(requires { requires bar<int>; });
 // expected-note@-5 {{because 'bar<int>' would be invalid}}
 
 }
+
+namespace GH91564 {
+
+template <class T> using A = struct B { // expected-error {{'GH91564::B' 
cannot be defined in a type alias template}}
+  template <class> void f() requires (T()); // expected-error {{atomic 
constraint must be of type 'bool' (found 'int')}} expected-note {{explicit 
instantiation refers here}}
+};
+template void B::f<void>(); // expected-error {{explicit instantiation of 
undefined function template 'f'}}
+
+template <class T> using C = struct D { // expected-error {{'GH91564::D' 
cannot be defined in a type alias template}}
+  using E = T;
+};
+template <class> void g() requires (D::E()); // expected-error {{atomic 
constraint must be of type 'bool' (found 'D::E' (aka 'int'))}} expected-note 
{{explicit instantiation refers here}}
+template void g<void>(); // expected-error {{explicit instantiation of 
undefined function template 'g'}}
+
+} // namespace GH91564

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to