diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaConcept.cpp | 27 | ||||
-rw-r--r-- | clang/test/SemaTemplate/concepts.cpp | 12 |
2 files changed, 31 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index f4df63c..9cbd1bd 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -604,6 +604,10 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments( return std::nullopt; const NormalizedConstraint::OccurenceList &Used = Constraint.mappingOccurenceList(); + // The empty MLTAL situation should only occur when evaluating non-dependent + // constraints. + if (!MLTAL.getNumSubstitutedLevels()) + MLTAL.addOuterTemplateArguments(TD, {}, /*Final=*/false); SubstitutedOuterMost = llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost()); unsigned Offset = 0; @@ -623,9 +627,7 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments( if (Offset < SubstitutedOuterMost.size()) SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset); - MLTAL.replaceOutermostTemplateArguments( - const_cast<NamedDecl *>(Constraint.getConstraintDecl()), - SubstitutedOuterMost); + MLTAL.replaceOutermostTemplateArguments(TD, SubstitutedOuterMost); return std::move(MLTAL); } @@ -956,11 +958,20 @@ ExprResult ConstraintSatisfactionChecker::Evaluate( ? Constraint.getPackSubstitutionIndex() : PackSubstitutionIndex; - Sema::InstantiatingTemplate _(S, ConceptId->getBeginLoc(), - Sema::InstantiatingTemplate::ConstraintsCheck{}, - ConceptId->getNamedConcept(), - MLTAL.getInnermost(), - Constraint.getSourceRange()); + Sema::InstantiatingTemplate InstTemplate( + S, ConceptId->getBeginLoc(), + Sema::InstantiatingTemplate::ConstraintsCheck{}, + ConceptId->getNamedConcept(), + // We may have empty template arguments when checking non-dependent + // nested constraint expressions. + // In such cases, non-SFINAE errors would have already been diagnosed + // during parameter mapping substitution, so the instantiating template + // arguments are less useful here. + MLTAL.getNumSubstitutedLevels() ? MLTAL.getInnermost() + : ArrayRef<TemplateArgument>{}, + Constraint.getSourceRange()); + if (InstTemplate.isInvalid()) + return ExprError(); unsigned Size = Satisfaction.Details.size(); diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 1dbb989..3fbe7c0 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1404,6 +1404,18 @@ static_assert(!std::is_constructible_v<span<4>, array<int, 3>>); } +namespace case7 { + +template <class _Tp, class _Up> +concept __same_as_impl = __is_same(_Tp, _Up); +template <class _Tp, class _Up> +concept same_as = __same_as_impl<_Tp, _Up>; +template <typename> +concept IsEntitySpec = + requires { requires same_as<void, void>; }; + +} + } namespace GH162125 { |