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 <mizve...@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@-1 {{non-type template parameter has incomplete type 'struct U1'}} + // expected-note@-2 {{forward declaration of 'PR51872_part1::U1'}} + + T1 t1 = 0; + // expected-error@-1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}} + // expected-note@-6 {{candidate template ignored: could not match 'T1<>' against 'int'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits