[clang] Fix CTAD not respect default template arguments that were added after the definition. (#75569)
Fixes https://github.com/llvm/llvm-project/issues/69987
This commit is contained in:
@@ -688,6 +688,9 @@ Bug Fixes in This Version
|
||||
(`#62157 <https://github.com/llvm/llvm-project/issues/62157>`_) and
|
||||
(`#64885 <https://github.com/llvm/llvm-project/issues/64885>`_) and
|
||||
(`#65568 <https://github.com/llvm/llvm-project/issues/65568>`_)
|
||||
- Fix an issue where clang doesn't respect detault template arguments that
|
||||
are added in a later redeclaration for CTAD.
|
||||
Fixes (#69987 <https://github.com/llvm/llvm-project/issues/69987>`_)
|
||||
|
||||
Bug Fixes to Compiler Builtins
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1824,6 +1824,15 @@ static void SetNestedNameSpecifier(Sema &S, TagDecl *T,
|
||||
T->setQualifierInfo(SS.getWithLocInContext(S.Context));
|
||||
}
|
||||
|
||||
// Returns the template parameter list with all default template argument
|
||||
// information.
|
||||
static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
|
||||
// Make sure we get the template parameter list from the most
|
||||
// recent declaration, since that is the only one that is guaranteed to
|
||||
// have all the default template argument information.
|
||||
return cast<TemplateDecl>(TD->getMostRecentDecl())->getTemplateParameters();
|
||||
}
|
||||
|
||||
DeclResult Sema::CheckClassTemplate(
|
||||
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
|
||||
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
|
||||
@@ -2061,13 +2070,13 @@ DeclResult Sema::CheckClassTemplate(
|
||||
if (!(TUK == TUK_Friend && CurContext->isDependentContext()) &&
|
||||
CheckTemplateParameterList(
|
||||
TemplateParams,
|
||||
PrevClassTemplate
|
||||
? PrevClassTemplate->getMostRecentDecl()->getTemplateParameters()
|
||||
: nullptr,
|
||||
PrevClassTemplate ? GetTemplateParameterList(PrevClassTemplate)
|
||||
: nullptr,
|
||||
(SS.isSet() && SemanticContext && SemanticContext->isRecord() &&
|
||||
SemanticContext->isDependentContext())
|
||||
? TPC_ClassTemplateMember
|
||||
: TUK == TUK_Friend ? TPC_FriendClassTemplate : TPC_ClassTemplate,
|
||||
: TUK == TUK_Friend ? TPC_FriendClassTemplate
|
||||
: TPC_ClassTemplate,
|
||||
SkipBody))
|
||||
Invalid = true;
|
||||
|
||||
@@ -2298,7 +2307,7 @@ struct ConvertConstructorToDeductionGuideTransform {
|
||||
// -- The template parameters are the template parameters of the class
|
||||
// template followed by the template parameters (including default
|
||||
// template arguments) of the constructor, if any.
|
||||
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
|
||||
TemplateParameterList *TemplateParams = GetTemplateParameterList(Template);
|
||||
if (FTD) {
|
||||
TemplateParameterList *InnerParams = FTD->getTemplateParameters();
|
||||
SmallVector<NamedDecl *, 16> AllParams;
|
||||
@@ -2424,7 +2433,7 @@ struct ConvertConstructorToDeductionGuideTransform {
|
||||
Params.push_back(NewParam);
|
||||
}
|
||||
|
||||
return buildDeductionGuide(Template->getTemplateParameters(), nullptr,
|
||||
return buildDeductionGuide(GetTemplateParameterList(Template), nullptr,
|
||||
ExplicitSpecifier(), TSI, Loc, Loc, Loc);
|
||||
}
|
||||
|
||||
@@ -5956,12 +5965,7 @@ bool Sema::CheckTemplateArgumentList(
|
||||
// template.
|
||||
TemplateArgumentListInfo NewArgs = TemplateArgs;
|
||||
|
||||
// Make sure we get the template parameter list from the most
|
||||
// recent declaration, since that is the only one that is guaranteed to
|
||||
// have all the default template argument information.
|
||||
TemplateParameterList *Params =
|
||||
cast<TemplateDecl>(Template->getMostRecentDecl())
|
||||
->getTemplateParameters();
|
||||
TemplateParameterList *Params = GetTemplateParameterList(Template);
|
||||
|
||||
SourceLocation RAngleLoc = NewArgs.getRAngleLoc();
|
||||
|
||||
|
||||
@@ -44,3 +44,13 @@ namespace Access {
|
||||
};
|
||||
D z = {Z(), {}};
|
||||
}
|
||||
|
||||
namespace GH69987 {
|
||||
template<class> struct X {};
|
||||
template<class = void> struct X;
|
||||
X x;
|
||||
|
||||
template<class T, class B> struct Y { Y(T); };
|
||||
template<class T, class B=void> struct Y ;
|
||||
Y y(1);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user