[clang] [clang] Fix bad error recovery when classes are defined inside template (PR #142278)
Artyom Zabroda via cfe-commits
cfe-commits at lists.llvm.org
Sat May 31 09:06:42 PDT 2025
https://github.com/ArtyomZabroda created https://github.com/llvm/llvm-project/pull/142278
Fixes #91564
This is my first pull request to the LLVM and I would appreciate any feedback.
>From 6fc280bb5583ee4f1713cb1447b8b86993b7abb7 Mon Sep 17 00:00:00 2001
From: Artyom Zabroda <artyomzabroda at gmail.com>
Date: Sat, 31 May 2025 18:44:21 +0300
Subject: [PATCH] [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
More information about the cfe-commits
mailing list