Skip to content

Commit db646e2

Browse files
committed
[Clang] Fix concept paramater mapping for SizeOfPackExpr
This expression is not handled by default in RAV, so our parameter mapping and cache mechanism don't work when it appears in a template argument list. There are a few other expressions, such as PackIndexingExpr and FunctionParmPackExpr, which are also no-ops by default. I don't have a test case for them now, so let's leave those until complain :/ There was also a bug in updating the parameter mapping, where the AssociatedDecl was not updated accordingly.
1 parent 4647cd7 commit db646e2

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

clang/lib/Sema/SemaConcept.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,6 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
264264

265265
UnsignedOrNone OuterPackSubstIndex;
266266

267-
TemplateArgument getPackSubstitutedTemplateArgument(TemplateArgument Arg) {
268-
assert(*SemaRef.ArgPackSubstIndex < Arg.pack_size());
269-
Arg = Arg.pack_begin()[*SemaRef.ArgPackSubstIndex];
270-
if (Arg.isPackExpansion())
271-
Arg = Arg.getPackExpansionPattern();
272-
return Arg;
273-
}
274-
275267
bool shouldVisitTemplateInstantiations() const { return true; }
276268

277269
public:
@@ -294,7 +286,7 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
294286
assert(Arg.getKind() == TemplateArgument::Pack &&
295287
"Missing argument pack");
296288

297-
Arg = getPackSubstitutedTemplateArgument(Arg);
289+
Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);
298290
}
299291

300292
UsedTemplateArgs.push_back(
@@ -312,7 +304,7 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
312304
if (NTTP->isParameterPack() && SemaRef.ArgPackSubstIndex) {
313305
assert(Arg.getKind() == TemplateArgument::Pack &&
314306
"Missing argument pack");
315-
Arg = getPackSubstitutedTemplateArgument(Arg);
307+
Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);
316308
}
317309

318310
UsedTemplateArgs.push_back(
@@ -363,6 +355,10 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
363355
return inherited::TraverseTemplateArgument(Arg);
364356
}
365357

358+
bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
359+
return TraverseDecl(SOPE->getPack());
360+
}
361+
366362
void VisitConstraint(const NormalizedConstraintWithParamMapping &Constraint) {
367363
if (!Constraint.hasParameterMapping()) {
368364
for (const auto &List : TemplateArgs)
@@ -2083,8 +2079,8 @@ bool SubstituteParameterMappings::substitute(ConceptIdConstraint &CC) {
20832079
/*UpdateArgsWithConversions=*/false))
20842080
return true;
20852081
auto TemplateArgs = *MLTAL;
2086-
TemplateArgs.replaceOutermostTemplateArguments(
2087-
TemplateArgs.getAssociatedDecl(0).first, CTAI.SugaredConverted);
2082+
TemplateArgs.replaceOutermostTemplateArguments(CSE->getNamedConcept(),
2083+
CTAI.SugaredConverted);
20882084
return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
20892085
InFoldExpr)
20902086
.substitute(CC.getNormalizedConstraint());

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6718,6 +6718,10 @@ struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
67186718
}
67196719
return true;
67206720
}
6721+
6722+
bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) override {
6723+
return TraverseDecl(SOPE->getPack());
6724+
}
67216725
};
67226726
}
67236727

clang/test/SemaTemplate/concepts.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,4 +1333,32 @@ static_assert(__cpp17_iterator<not_move_constructible>); \
13331333
// expected-note@#is_move_constructible_v {{because 'is_move_constructible_v<parameter_mapping_regressions::case3::not_move_constructible>' evaluated to false}}
13341334
}
13351335

1336+
namespace case4 {
1337+
1338+
template<bool b>
1339+
concept bool_ = b;
1340+
1341+
template<typename... Ts>
1342+
concept unary = bool_<sizeof...(Ts) == 1>;
1343+
1344+
static_assert(!unary<>);
1345+
static_assert(unary<void>);
1346+
1347+
}
1348+
1349+
namespace case5 {
1350+
1351+
template<int size>
1352+
concept true1 = size == size;
1353+
1354+
template<typename... Ts>
1355+
concept true2 = true1<sizeof...(Ts)>;
1356+
1357+
template<typename... Ts>
1358+
concept true3 = true2<Ts...>;
1359+
1360+
static_assert(true3<void>);
1361+
1362+
}
1363+
13361364
}

0 commit comments

Comments
 (0)