diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h index 80d557d3827fd..2f5be9d0b0325 100644 --- a/clang/include/clang/Sema/SemaConcept.h +++ b/clang/include/clang/Sema/SemaConcept.h @@ -78,7 +78,7 @@ struct NormalizedConstraint { unsigned Kind : 5; LLVM_PREFERRED_TYPE(FoldOperatorKind) unsigned FoldOperator : 1; - unsigned : 26; + unsigned Placeholder : 26; OccurenceList Indexes; TemplateArgumentLoc *Args; const Expr *Pattern; @@ -125,6 +125,7 @@ struct NormalizedConstraint { NormalizedConstraint *Constraint) : FoldExpanded{llvm::to_underlying(ConstraintKind::FoldExpanded), llvm::to_underlying(OpKind), + /*Placeholder=*/0, /*Indexes=*/{}, /*Args=*/nullptr, Pattern, diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index d674f3ada5837..bfd713d981f60 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -351,7 +351,11 @@ static std::optional SubstitutionInTemplateArguments( Sema &S, const NormalizedConstraintWithParamMapping &Constraint, const NamedDecl *Template, MultiLevelTemplateArgumentList MLTAL, - llvm::SmallVector &SubstitutedOuterMost) { + llvm::SmallVector &SubstitutedOuterMost, + // FIXME: Having both PackSubstitutionIndex and + // NormalizedConstraintWithParamMapping::getPackSubstitutionIndex is + // confusing + UnsignedOrNone PackSubstitutionIndex) { Sema::InstantiatingTemplate Inst( S, Constraint.getBeginLoc(), @@ -369,7 +373,9 @@ SubstitutionInTemplateArguments( TemplateArgumentListInfo SubstArgs; if (Constraint.hasParameterMapping()) { Sema::ArgPackSubstIndexRAII SubstIndex( - S, Constraint.getPackSubstitutionIndex()); + S, Constraint.getPackSubstitutionIndex() + ? Constraint.getPackSubstitutionIndex() + : PackSubstitutionIndex); if (S.SubstTemplateArgumentsInParameterMapping( Constraint.getParameterMapping(), MLTAL, SubstArgs) || Trap.hasErrorOccurred()) @@ -405,11 +411,12 @@ static bool calculateConstraintSatisfaction( llvm::SmallVector SubstitutedOuterMost; std::optional SubstitutedArgs = SubstitutionInTemplateArguments(S, Constraint, Template, MLTAL, - SubstitutedOuterMost); + SubstitutedOuterMost, + PackSubstitutionIndex); if (!SubstitutedArgs) return false; - Sema::ArgPackSubstIndexRAII(S, PackSubstitutionIndex); + Sema::ArgPackSubstIndexRAII SubstIndex(S, PackSubstitutionIndex); ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(S, Constraint.getConstraintExpr(), Template, TemplateNameLoc, *SubstitutedArgs, Satisfaction); @@ -526,7 +533,8 @@ static bool calculateConstraintSatisfaction( S, static_cast( FE.getNormalizedPattern()), - Template, MLTAL, SubstitutedOuterMost); + // FIXME: Is PackSubstitutionIndex correct? + Template, MLTAL, SubstitutedOuterMost, S.ArgPackSubstIndex); if (!SubstitutedArgs) return false; @@ -548,7 +556,9 @@ static bool calculateConstraintSatisfaction( bool Success = calculateConstraintSatisfaction( S, FE.getNormalizedPattern(), Template, TemplateNameLoc, *SubstitutedArgs, Satisfaction, UnsignedOrNone(I)); - if (!Success) + // SFINAE errors shouldn't prevent disjunction from evaluating + // FIXME: Does !Success == SFINAE errors occurred? + if (!Success && Conjunction) return false; if (!Conjunction && Satisfaction.IsSatisfied) { Satisfaction.Details.erase(Satisfaction.Details.begin() + EffectiveDetailEndIndex, @@ -556,6 +566,10 @@ static bool calculateConstraintSatisfaction( break; } } + // Satisfaction.IsSatisfied might be overwritten. + // How to handle errors here ?? Shall we substitute into the concept? + if (Satisfaction.Details.size() != EffectiveDetailEndIndex) + Satisfaction.IsSatisfied = false; return true; } @@ -569,11 +583,6 @@ static bool calculateConstraintSatisfaction( S, Constraint.getConceptId()->getNamedConcept()->getDeclContext(), /*NewThisContext=*/false); - llvm::SmallVector SubstitutedOuterMost; - std::optional SubstitutedArgs = - SubstitutionInTemplateArguments(S, Constraint, Template, MLTAL, - SubstitutedOuterMost); - Sema::InstantiatingTemplate Tpl( S, Constraint.getConceptId()->getBeginLoc(), Sema::InstantiatingTemplate::ConstraintsCheck{}, @@ -588,6 +597,12 @@ static bool calculateConstraintSatisfaction( if (Size != Satisfaction.Details.size()) { + llvm::SmallVector SubstitutedOuterMost; + std::optional SubstitutedArgs = + SubstitutionInTemplateArguments(S, Constraint, Template, MLTAL, + SubstitutedOuterMost, + PackSubstitutionIndex); + if (!SubstitutedArgs) return Ok; @@ -633,7 +648,7 @@ static bool calculateConstraintSatisfaction( SubstitutedConceptId.getAs() ->getConceptReference())); - Satisfaction.Details.push_back(nullptr); + // Satisfaction.Details.push_back(nullptr); } return Ok; } @@ -1774,11 +1789,11 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr( return nullptr; if (FE->isRightFold()) - RHS = FoldExpandedConstraint::Create(S.getASTContext(), - FE->getPattern(), Kind, RHS); - else LHS = FoldExpandedConstraint::Create(S.getASTContext(), FE->getPattern(), Kind, LHS); + else + RHS = FoldExpandedConstraint::Create(S.getASTContext(), + FE->getPattern(), Kind, RHS); return CompoundConstraint::Create( S.getASTContext(), LHS, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index a465f0dcc0562..8cc73b09c3fac 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5080,10 +5080,11 @@ bool Sema::CheckTemplateTypeArgument( } default: { // We allow instantiating a template with template argument packs when - // building deduction guides. + // building deduction guides or mapping constraint template parameters. if (Arg.getKind() == TemplateArgument::Pack && - CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::BuildingDeductionGuides) { + (CodeSynthesisContexts.back().Kind == + Sema::CodeSynthesisContext::BuildingDeductionGuides || + inParameterMappingSubstitution())) { SugaredConverted.push_back(Arg); CanonicalConverted.push_back(Arg); return false; diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp index 55eeb7f564870..fb2fc95949dab 100644 --- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp +++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp @@ -158,6 +158,7 @@ static_assert(And1() == 1); // expected-error {{no matching function for static_assert(And2() == 2); static_assert(And2() == 2); +// FIXME: Should it compile?? static_assert(And2() == 2); static_assert(And2() == 2); // expected-error {{no matching function for call to 'And2'}}