Skip to content

Commit 6fc280b

Browse files
committed
[clang] Fix bad error recovery when classes are defined inside template aliases
1 parent 8160276 commit 6fc280b

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

clang/lib/Sema/SemaConcept.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ static ExprResult EvaluateAtomicConstraint(
220220
if (Inst.isInvalid())
221221
return ExprError();
222222

223+
if (const TemplateTypeParmType *TTPT =
224+
dyn_cast<TemplateTypeParmType>(AtomicExpr->getType().getDesugaredType(S.Context))) {
225+
TemplateTypeParmDecl *TTPD = TTPT->getDecl();
226+
if (TTPD->isInvalidDecl()) {
227+
return ExprError();
228+
}
229+
}
230+
223231
llvm::FoldingSetNodeID ID;
224232
if (Template &&
225233
DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13717,8 +13717,15 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS,
1371713717
const ParsedAttributesView &AttrList,
1371813718
TypeResult Type, Decl *DeclFromDeclSpec) {
1371913719

13720-
if (Type.isInvalid())
13720+
if (Type.isInvalid()) {
13721+
for (TemplateParameterList *TPL : TemplateParamLists) {
13722+
for (NamedDecl *D : *TPL) {
13723+
D->setInvalidDecl(true);
13724+
}
13725+
}
1372113726
return nullptr;
13727+
}
13728+
1372213729

1372313730
bool Invalid = false;
1372413731
DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name);

clang/test/SemaCXX/concept-crash-on-diagnostic.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,16 @@ concept atomicish = requires() {
6060
};
6161
atomicish<int> f(); // expected-error {{expected 'auto' or 'decltype(auto)' after concept name}}
6262
} // namespace GH138820
63+
64+
namespace GH91564 {
65+
template <class T> using A = struct B { // expected-error {{'GH91564::B' cannot be defined in a type alias template}}
66+
template <class> void f() requires (T()); // expected-note {{candidate template ignored: failed template argument deduction}}
67+
};
68+
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}}
69+
70+
template <class T> using C = struct D { // expected-error {{'GH91564::D' cannot be defined in a type alias template}}
71+
using E = T;
72+
};
73+
template <class> void g() requires (D::E()); // expected-note {{candidate template ignored: failed template argument deduction}}
74+
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}}
75+
}

0 commit comments

Comments
 (0)