mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
[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@gmail.com> Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D110460
This commit is contained in:
parent
f4cfda03d6
commit
37adc4f957
@ -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 *
|
||||
|
@ -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'}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user