Skip to content

Commit f0d65ac

Browse files
committed
[Clang] Drop unrelated template arguments in substituted parameter mapping
The unused template arguments living in different levels would confuse the substitution otherwise. Fixes a regression on trunk.
1 parent e9e9ba4 commit f0d65ac

File tree

3 files changed

+47
-21
lines changed

3 files changed

+47
-21
lines changed

clang/include/clang/Sema/Template.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ enum class TemplateSubstitutionKind : char {
205205

206206
/// Add a new outmost level to the multi-level template argument
207207
/// list.
208-
/// A 'Final' substitution means that Subst* nodes won't be built
209-
/// for the replacements.
208+
/// A 'Final' substitution means that these Args are not needed to be
209+
/// resugared later.
210210
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args,
211211
bool Final) {
212212
assert(!NumRetainedOuterLevels &&

clang/lib/Sema/SemaConcept.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ std::optional<MultiLevelTemplateArgumentList>
565565
ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
566566
const NormalizedConstraintWithParamMapping &Constraint,
567567
MultiLevelTemplateArgumentList MLTAL,
568-
llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost) {
568+
llvm::SmallVector<TemplateArgument> &SubstitutedOutermost) {
569569

570570
if (!Constraint.hasParameterMapping())
571571
return std::move(MLTAL);
@@ -606,38 +606,39 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
606606
Constraint.mappingOccurenceList();
607607
// The empty MLTAL situation should only occur when evaluating non-dependent
608608
// constraints.
609-
if (!MLTAL.getNumSubstitutedLevels())
610-
MLTAL.addOuterTemplateArguments(TD, {}, /*Final=*/false);
611-
SubstitutedOuterMost =
612-
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
609+
if (MLTAL.getNumSubstitutedLevels())
610+
SubstitutedOutermost =
611+
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
613612
unsigned Offset = 0;
614613
for (unsigned I = 0, MappedIndex = 0; I < Used.size(); I++) {
615614
TemplateArgument Arg;
616615
if (Used[I])
617616
Arg = S.Context.getCanonicalTemplateArgument(
618617
CTAI.SugaredConverted[MappedIndex++]);
619-
if (I < SubstitutedOuterMost.size()) {
620-
SubstitutedOuterMost[I] = Arg;
618+
if (I < SubstitutedOutermost.size()) {
619+
SubstitutedOutermost[I] = Arg;
621620
Offset = I + 1;
622621
} else {
623-
SubstitutedOuterMost.push_back(Arg);
624-
Offset = SubstitutedOuterMost.size();
622+
SubstitutedOutermost.push_back(Arg);
623+
Offset = SubstitutedOutermost.size();
625624
}
626625
}
627-
if (Offset < SubstitutedOuterMost.size())
628-
SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset);
626+
if (Offset < SubstitutedOutermost.size())
627+
SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
629628

630-
MLTAL.replaceOutermostTemplateArguments(TD, SubstitutedOuterMost);
631-
return std::move(MLTAL);
629+
MultiLevelTemplateArgumentList SubstitutedTemplateArgs;
630+
SubstitutedTemplateArgs.addOuterTemplateArguments(TD, SubstitutedOutermost,
631+
/*Final=*/false);
632+
return std::move(SubstitutedTemplateArgs);
632633
}
633634

634635
ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
635636
const AtomicConstraint &Constraint,
636637
const MultiLevelTemplateArgumentList &MLTAL) {
637638

638-
llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
639+
llvm::SmallVector<TemplateArgument> SubstitutedOutermost;
639640
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
640-
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOuterMost);
641+
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
641642
if (!SubstitutedArgs) {
642643
Satisfaction.IsSatisfied = false;
643644
return ExprEmpty();
@@ -785,13 +786,13 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
785786
FoldExpandedConstraint::FoldOperatorKind::And;
786787
unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
787788

788-
llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
789+
llvm::SmallVector<TemplateArgument> SubstitutedOutermost;
789790
// FIXME: Is PackSubstitutionIndex correct?
790791
llvm::SaveAndRestore _(PackSubstitutionIndex, S.ArgPackSubstIndex);
791792
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
792793
SubstitutionInTemplateArguments(
793794
static_cast<const NormalizedConstraintWithParamMapping &>(Constraint),
794-
MLTAL, SubstitutedOuterMost);
795+
MLTAL, SubstitutedOutermost);
795796
if (!SubstitutedArgs) {
796797
Satisfaction.IsSatisfied = false;
797798
return ExprError();
@@ -879,9 +880,9 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
879880
const MultiLevelTemplateArgumentList &MLTAL, unsigned Size) {
880881
const ConceptReference *ConceptId = Constraint.getConceptId();
881882

882-
llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
883+
llvm::SmallVector<TemplateArgument> SubstitutedOutermost;
883884
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
884-
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOuterMost);
885+
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
885886

886887
if (!SubstitutedArgs) {
887888
Satisfaction.IsSatisfied = false;

clang/test/SemaTemplate/concepts.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,31 @@ concept IsEntitySpec =
14161416

14171417
}
14181418

1419+
namespace case8 {
1420+
1421+
template <class T>
1422+
struct type_identity {
1423+
using type = T;
1424+
};
1425+
1426+
template <typename Inner>
1427+
struct Cat {};
1428+
1429+
template <typename T>
1430+
concept CatConcept = requires {
1431+
[]<class Inner>(type_identity<Cat<Inner>>) {}(type_identity<T>{});
1432+
};
1433+
1434+
template <typename Dummy>
1435+
struct Feeder {
1436+
template <CatConcept Dummy2>
1437+
void feed() noexcept {}
1438+
};
1439+
1440+
void main() { Feeder<int>{}.feed<Cat<int>>(); }
1441+
1442+
}
1443+
14191444
}
14201445

14211446
namespace GH162125 {

0 commit comments

Comments
 (0)