[clang] 37adc4f - [clang] set templates as invalid when any of the parameters are invalid
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 24 19:04:55 PDT 2021
Author: Matheus Izvekov
Date: 2021-09-25T04:04:47+02:00
New Revision: 37adc4f957c2383a625e2e593ba1d18a25d92b91
URL: https://github.com/llvm/llvm-project/commit/37adc4f957c2383a625e2e593ba1d18a25d92b91
DIFF: https://github.com/llvm/llvm-project/commit/37adc4f957c2383a625e2e593ba1d18a25d92b91.diff
LOG: [clang] set templates as invalid when any of the parameters are invalid
See PR51872 for the original repro.
This fixes a crash when converting a templated constructor into a deduction
guide, in case any of the template parameters were invalid.
Signed-off-by: Matheus Izvekov <mizvekov at gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D110460
Added:
Modified:
clang/lib/AST/DeclTemplate.cpp
clang/test/SemaTemplate/deduction-crash.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index a25185067b9c5..fa73c53866490 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -165,14 +165,20 @@ unsigned TemplateParameterList::getDepth() const {
return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
}
-static void AdoptTemplateParameterList(TemplateParameterList *Params,
+static bool AdoptTemplateParameterList(TemplateParameterList *Params,
DeclContext *Owner) {
+ bool Invalid = false;
for (NamedDecl *P : *Params) {
P->setDeclContext(Owner);
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
- AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
+ if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
+ Invalid = true;
+
+ if (P->isInvalidDecl())
+ Invalid = true;
}
+ return Invalid;
}
void TemplateParameterList::
@@ -339,14 +345,15 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
// FunctionTemplateDecl Implementation
//===----------------------------------------------------------------------===//
-FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl) {
- AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
- return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
+FunctionTemplateDecl *
+FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl) {
+ bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
+ auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
+ if (Invalid)
+ TD->setInvalidDecl();
+ return TD;
}
FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -438,15 +445,16 @@ void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
-ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
- DeclContext *DC,
+ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl) {
- AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-
- return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+ bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
+ auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+ if (Invalid)
+ TD->setInvalidDecl();
+ return TD;
}
ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1005,8 +1013,11 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
Expr *ConstraintExpr) {
- AdoptTemplateParameterList(Params, DC);
- return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
+ bool Invalid = AdoptTemplateParameterList(Params, DC);
+ auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
+ if (Invalid)
+ TD->setInvalidDecl();
+ return TD;
}
ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
@@ -1039,7 +1050,8 @@ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
SpecializedTemplate, Args, PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
InstantiatedFromMember(nullptr, false) {
- AdoptTemplateParameterList(Params, this);
+ if (AdoptTemplateParameterList(Params, this))
+ setInvalidDecl();
}
ClassTemplatePartialSpecializationDecl *
@@ -1097,14 +1109,15 @@ FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
// TypeAliasTemplateDecl Implementation
//===----------------------------------------------------------------------===//
-TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl) {
- AdoptTemplateParameterList(Params, DC);
- return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
+TypeAliasTemplateDecl *
+TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl) {
+ bool Invalid = AdoptTemplateParameterList(Params, DC);
+ auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
+ if (Invalid)
+ TD->setInvalidDecl();
+ return TD;
}
TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1151,8 +1164,11 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
VarDecl *Decl) {
- AdoptTemplateParameterList(Params, DC);
- return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
+ bool Invalid = AdoptTemplateParameterList(Params, DC);
+ auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
+ if (Invalid)
+ TD->setInvalidDecl();
+ return TD;
}
VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -1334,8 +1350,8 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
TInfo, S, Args),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
InstantiatedFromMember(nullptr, false) {
- // TODO: The template parameters should be in DC by now. Verify.
- // AdoptTemplateParameterList(Params, DC);
+ if (AdoptTemplateParameterList(Params, DC))
+ setInvalidDecl();
}
VarTemplatePartialSpecializationDecl *
diff --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp
index 2c58fefa065fd..86ec9f7980a7d 100644
--- a/clang/test/SemaTemplate/deduction-crash.cpp
+++ b/clang/test/SemaTemplate/deduction-crash.cpp
@@ -161,3 +161,13 @@ evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot
}
}
+
+namespace PR51872_part1 {
+ template<int> class T1 { template <struct U1> T1(); };
+ // expected-error at -1 {{non-type template parameter has incomplete type 'struct U1'}}
+ // expected-note at -2 {{forward declaration of 'PR51872_part1::U1'}}
+
+ T1 t1 = 0;
+ // expected-error at -1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}}
+ // expected-note at -6 {{candidate template ignored: could not match 'T1<>' against 'int'}}
+}
More information about the cfe-commits
mailing list