Skip to content

Commit 1857df3

Browse files
ilya-biryukovyuxuanchen1997
authored andcommitted
[Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (#99880)
Summary: This addresses the FIXME in the code. There will be tests for the new behavior in an upcoming #86265, which also addresses other bugs that prevent exposing the wrong results of `ContainsUnexpandedPacks` in the outputs of the compiler without crashes. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251126
1 parent 31a8c84 commit 1857df3

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

clang/lib/AST/DeclTemplate.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ using namespace clang;
4444
// TemplateParameterList Implementation
4545
//===----------------------------------------------------------------------===//
4646

47+
template <class TemplateParam>
48+
static bool
49+
DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
50+
return P.hasDefaultArgument() &&
51+
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
52+
}
4753

4854
TemplateParameterList::TemplateParameterList(const ASTContext& C,
4955
SourceLocation TemplateLoc,
@@ -61,27 +67,30 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
6167

6268
bool IsPack = P->isTemplateParameterPack();
6369
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64-
if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
70+
if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
71+
DefaultTemplateArgumentContainsUnexpandedPack(*NTTP)))
6572
ContainsUnexpandedParameterPack = true;
6673
if (NTTP->hasPlaceholderTypeConstraint())
6774
HasConstrainedParameters = true;
6875
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
6976
if (!IsPack &&
70-
TTP->getTemplateParameters()->containsUnexpandedParameterPack())
77+
(TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
78+
DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) {
7179
ContainsUnexpandedParameterPack = true;
80+
}
7281
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73-
if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74-
if (TC->getImmediatelyDeclaredConstraint()
75-
->containsUnexpandedParameterPack())
76-
ContainsUnexpandedParameterPack = true;
82+
if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) {
83+
ContainsUnexpandedParameterPack = true;
84+
} else if (const TypeConstraint *TC = TTP->getTypeConstraint();
85+
TC && TC->getImmediatelyDeclaredConstraint()
86+
->containsUnexpandedParameterPack()) {
87+
ContainsUnexpandedParameterPack = true;
7788
}
7889
if (TTP->hasTypeConstraint())
7990
HasConstrainedParameters = true;
8091
} else {
8192
llvm_unreachable("unexpected template parameter type");
8293
}
83-
// FIXME: If a default argument contains an unexpanded parameter pack, the
84-
// template parameter list does too.
8594
}
8695

8796
if (HasRequiresClause) {

0 commit comments

Comments
 (0)