[clang] [Clang] Improve error recovery for invalid alias templates (PR #235456)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 25 07:28:03 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Devansh (Dash198)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/235456.diff
2 Files Affected:
- (modified) clang/lib/Sema/SemaDecl.cpp (+18-1)
- (modified) clang/test/SemaCXX/concept-crash-on-diagnostic.cpp (+15)
``````````diff
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 at -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
``````````
</details>
https://github.com/llvm/llvm-project/pull/235456
More information about the cfe-commits
mailing list