https://github.com/ArtyomZabroda updated 
https://github.com/llvm/llvm-project/pull/142278

>From 6fc280bb5583ee4f1713cb1447b8b86993b7abb7 Mon Sep 17 00:00:00 2001
From: Artyom Zabroda <artyomzabr...@gmail.com>
Date: Sat, 31 May 2025 18:44:21 +0300
Subject: [PATCH 1/2] [clang] Fix bad error recovery when classes are defined
 inside template aliases

---
 clang/lib/Sema/SemaConcept.cpp                     |  8 ++++++++
 clang/lib/Sema/SemaDeclCXX.cpp                     |  9 ++++++++-
 clang/test/SemaCXX/concept-crash-on-diagnostic.cpp | 13 +++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index c6a54dc141ded..1c654f46e23b3 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -220,6 +220,14 @@ static ExprResult EvaluateAtomicConstraint(
     if (Inst.isInvalid())
       return ExprError();
 
+    if (const TemplateTypeParmType *TTPT =
+        
dyn_cast<TemplateTypeParmType>(AtomicExpr->getType().getDesugaredType(S.Context)))
 {
+      TemplateTypeParmDecl *TTPD = TTPT->getDecl();
+      if (TTPD->isInvalidDecl()) {
+        return ExprError();
+      }
+    }
+
     llvm::FoldingSetNodeID ID;
     if (Template &&
         DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 55e078f3180a2..3efd18c0dcd96 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13717,8 +13717,15 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, 
AccessSpecifier AS,
                                   const ParsedAttributesView &AttrList,
                                   TypeResult Type, Decl *DeclFromDeclSpec) {
 
-  if (Type.isInvalid())
+  if (Type.isInvalid()) {
+    for (TemplateParameterList *TPL : TemplateParamLists) {
+      for (NamedDecl *D : *TPL) {
+        D->setInvalidDecl(true);
+      }
+    }
     return nullptr;
+  }
+    
 
   bool Invalid = false;
   DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name);
diff --git a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp 
b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
index 1efed72522fef..af254828b0fe7 100644
--- a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
+++ b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
@@ -60,3 +60,16 @@ concept atomicish = requires() {
 };
 atomicish<int> f(); // expected-error {{expected 'auto' or 'decltype(auto)' 
after concept name}}
 } // namespace GH138820
+
+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-note {{candidate 
template ignored: failed template argument deduction}}
+};
+template void B::f<void>(); // expected-error {{explicit instantiation of 'f' 
does not refer to a function template, variable template, member function, 
member class, or static data member}}
+
+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-note {{candidate 
template ignored: failed template argument deduction}}
+template void g<void>(); // expected-error {{explicit instantiation of 'g' 
does not refer to a function template, variable template, member function, 
member class, or static data member}}
+}
\ No newline at end of file

>From c52af95007c2efaac1d44f3ff36e6a8021d6b70f Mon Sep 17 00:00:00 2001
From: Artyom Zabroda <artyomzabr...@gmail.com>
Date: Wed, 4 Jun 2025 14:16:26 +0300
Subject: [PATCH 2/2] very inaccurate fix

---
 clang/include/clang/Parse/Parser.h              |  2 ++
 clang/lib/Parse/ParseDeclCXX.cpp                | 17 +++++++++++++++++
 clang/lib/Sema/SemaConcept.cpp                  |  8 --------
 clang/lib/Sema/SemaDecl.cpp                     |  4 ++--
 clang/lib/Sema/SemaDeclCXX.cpp                  |  9 +--------
 .../SemaCXX/concept-crash-on-diagnostic.cpp     |  8 ++++----
 6 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index c4bef4729fd36..90f17465bce7d 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -8909,6 +8909,8 @@ class Parser : public CodeCompletionHandler {
                             bool OuterMightBeMessageSend = false);
 
   ///@}
+
+  TemplateParameterLists *TemplateParamsFromAlias = nullptr;
 };
 
 } // end namespace clang
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 2cf33a856c4f4..4069d257b0150 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -886,11 +886,17 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
         << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));
 
   Decl *DeclFromDeclSpec = nullptr;
+
+  this->TemplateParamsFromAlias = TemplateInfo.TemplateParams;
+
   TypeResult TypeAlias =
       ParseTypeName(nullptr,
                     TemplateInfo.Kind != ParsedTemplateKind::NonTemplate ? 
DeclaratorContext::AliasTemplate
                                       : DeclaratorContext::AliasDecl,
                     AS, &DeclFromDeclSpec, &Attrs);
+
+  this->TemplateParamsFromAlias = nullptr;
+
   if (OwnedType)
     *OwnedType = DeclFromDeclSpec;
 
@@ -2173,6 +2179,17 @@ void Parser::ParseClassSpecifier(tok::TokenKind 
TagTokKind,
     assert(Tok.is(tok::l_brace) ||
            (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
            isClassCompatibleKeyword());
+
+    if (TemplateParamsFromAlias) {
+      for (const TemplateParameterList *TPL : *TemplateParamsFromAlias) {
+        for (NamedDecl *D : *TPL) {
+          D->setInvalidDecl(true);
+          auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D);
+          TTPD->setTypeForDecl(Actions.Context.IntTy.getTypePtr());
+        }
+      }
+    }
+
     if (SkipBody.ShouldSkip)
       SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
                                  TagOrTempResult.get());
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 1c654f46e23b3..c6a54dc141ded 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -220,14 +220,6 @@ static ExprResult EvaluateAtomicConstraint(
     if (Inst.isInvalid())
       return ExprError();
 
-    if (const TemplateTypeParmType *TTPT =
-        
dyn_cast<TemplateTypeParmType>(AtomicExpr->getType().getDesugaredType(S.Context)))
 {
-      TemplateTypeParmDecl *TTPD = TTPT->getDecl();
-      if (TTPD->isInvalidDecl()) {
-        return ExprError();
-      }
-    }
-
     llvm::FoldingSetNodeID ID;
     if (Template &&
         DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 86b871396ec90..50c09bd3cdea7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -288,8 +288,8 @@ static ParsedType buildNamedType(Sema &S, const 
CXXScopeSpec *SS, QualType T,
   case Type::ObjCTypeParam:
   case Type::TemplateTypeParm:
     return ParsedType::make(T);
-  default:
-    llvm_unreachable("Unexpected Type Class");
+  //default:
+    //llvm_unreachable("Unexpected Type Class");
   }
 
   if (!SS || SS->isEmpty())
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3efd18c0dcd96..55e078f3180a2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13717,15 +13717,8 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, 
AccessSpecifier AS,
                                   const ParsedAttributesView &AttrList,
                                   TypeResult Type, Decl *DeclFromDeclSpec) {
 
-  if (Type.isInvalid()) {
-    for (TemplateParameterList *TPL : TemplateParamLists) {
-      for (NamedDecl *D : *TPL) {
-        D->setInvalidDecl(true);
-      }
-    }
+  if (Type.isInvalid())
     return nullptr;
-  }
-    
 
   bool Invalid = false;
   DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name);
diff --git a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp 
b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
index af254828b0fe7..fa3eb1372bd3f 100644
--- a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
+++ b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
@@ -63,13 +63,13 @@ atomicish<int> f(); // expected-error {{expected 'auto' or 
'decltype(auto)' afte
 
 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-note {{candidate 
template ignored: failed template argument deduction}}
+  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 'f' 
does not refer to a function template, variable template, member function, 
member class, or static data member}}
+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-note {{candidate 
template ignored: failed template argument deduction}}
-template void g<void>(); // expected-error {{explicit instantiation of 'g' 
does not refer to a function template, variable template, member function, 
member class, or static data member}}
+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'}}
 }
\ No newline at end of file

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to