Skip to content

Commit 688cbe4

Browse files
authored
[Clang] Fix a bug when checking non-dependent constraints (#162969)
We check the non-dependent constraints early with empty template arguments when we build a nested requirement. Therefore we cannot assume a non-empty MLTAL within the Checker. No release note because this is a regression on trunk.
1 parent 5a05fa1 commit 688cbe4

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

clang/lib/Sema/SemaConcept.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,10 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
604604
return std::nullopt;
605605
const NormalizedConstraint::OccurenceList &Used =
606606
Constraint.mappingOccurenceList();
607+
// The empty MLTAL situation should only occur when evaluating non-dependent
608+
// constraints.
609+
if (!MLTAL.getNumSubstitutedLevels())
610+
MLTAL.addOuterTemplateArguments(TD, {}, /*Final=*/false);
607611
SubstitutedOuterMost =
608612
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
609613
unsigned Offset = 0;
@@ -623,9 +627,7 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
623627
if (Offset < SubstitutedOuterMost.size())
624628
SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset);
625629

626-
MLTAL.replaceOutermostTemplateArguments(
627-
const_cast<NamedDecl *>(Constraint.getConstraintDecl()),
628-
SubstitutedOuterMost);
630+
MLTAL.replaceOutermostTemplateArguments(TD, SubstitutedOuterMost);
629631
return std::move(MLTAL);
630632
}
631633

@@ -956,11 +958,20 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
956958
? Constraint.getPackSubstitutionIndex()
957959
: PackSubstitutionIndex;
958960

959-
Sema::InstantiatingTemplate _(S, ConceptId->getBeginLoc(),
960-
Sema::InstantiatingTemplate::ConstraintsCheck{},
961-
ConceptId->getNamedConcept(),
962-
MLTAL.getInnermost(),
963-
Constraint.getSourceRange());
961+
Sema::InstantiatingTemplate InstTemplate(
962+
S, ConceptId->getBeginLoc(),
963+
Sema::InstantiatingTemplate::ConstraintsCheck{},
964+
ConceptId->getNamedConcept(),
965+
// We may have empty template arguments when checking non-dependent
966+
// nested constraint expressions.
967+
// In such cases, non-SFINAE errors would have already been diagnosed
968+
// during parameter mapping substitution, so the instantiating template
969+
// arguments are less useful here.
970+
MLTAL.getNumSubstitutedLevels() ? MLTAL.getInnermost()
971+
: ArrayRef<TemplateArgument>{},
972+
Constraint.getSourceRange());
973+
if (InstTemplate.isInvalid())
974+
return ExprError();
964975

965976
unsigned Size = Satisfaction.Details.size();
966977

clang/test/SemaTemplate/concepts.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,18 @@ static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
14041404

14051405
}
14061406

1407+
namespace case7 {
1408+
1409+
template <class _Tp, class _Up>
1410+
concept __same_as_impl = __is_same(_Tp, _Up);
1411+
template <class _Tp, class _Up>
1412+
concept same_as = __same_as_impl<_Tp, _Up>;
1413+
template <typename>
1414+
concept IsEntitySpec =
1415+
requires { requires same_as<void, void>; };
1416+
1417+
}
1418+
14071419
}
14081420

14091421
namespace GH162125 {

0 commit comments

Comments
 (0)