Skip to content

Commit 6a7422e

Browse files
committed
[Sema] Default arguments for template parameters affect ContainsUnexpandedPacks
This addresses the FIXME in the code. There are tests for the new behavior in a follow up fix for #99877, which also addresses other bugs that prevent exposing the wrong results of `ContainsUnexpandedPacks` in the outputs of the compiler without crashes.
1 parent 5b54f36 commit 6a7422e

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

clang/lib/AST/DeclTemplate.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
6161

6262
bool IsPack = P->isTemplateParameterPack();
6363
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64-
if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
65-
ContainsUnexpandedParameterPack = true;
64+
if (!IsPack) {
65+
if (NTTP->getType()->containsUnexpandedParameterPack())
66+
ContainsUnexpandedParameterPack = true;
67+
else if (NTTP->hasDefaultArgument() &&
68+
NTTP->getDefaultArgument()
69+
.getArgument()
70+
.containsUnexpandedParameterPack())
71+
ContainsUnexpandedParameterPack = true;
72+
}
6673
if (NTTP->hasPlaceholderTypeConstraint())
6774
HasConstrainedParameters = true;
6875
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69-
if (!IsPack &&
70-
TTP->getTemplateParameters()->containsUnexpandedParameterPack())
71-
ContainsUnexpandedParameterPack = true;
72-
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73-
if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74-
if (TC->getImmediatelyDeclaredConstraint()
75-
->containsUnexpandedParameterPack())
76+
if (!IsPack) {
77+
if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
7678
ContainsUnexpandedParameterPack = true;
79+
else if (TTP->hasDefaultArgument() &&
80+
TTP->getDefaultArgument()
81+
.getArgument()
82+
.containsUnexpandedParameterPack())
83+
ContainsUnexpandedParameterPack = true;
84+
}
85+
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
86+
if (!IsPack && TTP->hasDefaultArgument() &&
87+
TTP->getDefaultArgument()
88+
.getArgument()
89+
.containsUnexpandedParameterPack()) {
90+
ContainsUnexpandedParameterPack = true;
91+
} else if (const TypeConstraint *TC = TTP->getTypeConstraint();
92+
TC && TC->getImmediatelyDeclaredConstraint()
93+
->containsUnexpandedParameterPack()) {
94+
ContainsUnexpandedParameterPack = true;
7795
}
7896
if (TTP->hasTypeConstraint())
7997
HasConstrainedParameters = true;
8098
} else {
8199
llvm_unreachable("unexpected template parameter type");
82100
}
83-
// FIXME: If a default argument contains an unexpanded parameter pack, the
84-
// template parameter list does too.
85101
}
86102

87103
if (HasRequiresClause) {

0 commit comments

Comments
 (0)