Skip to content

Commit

Permalink
[clang] Fix CTAD not respect default template arguments that were add…
Browse files Browse the repository at this point in the history
…ed after the definition. (llvm#75569)

Fixes llvm#69987
  • Loading branch information
hokein authored Dec 18, 2023
1 parent 465ecf8 commit 42239d2
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
28 changes: 16 additions & 12 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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();

Expand Down
10 changes: 10 additions & 0 deletions clang/test/SemaTemplate/ctad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};

0 comments on commit 42239d2

Please sign in to comment.