Skip to content

[clang] Fix CTAD not respect default template arguments that were added after the definition. #75569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an unrelated change and it looks funny.

: 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);
};