Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/SemaConcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -125,6 +125,7 @@ struct NormalizedConstraint {
NormalizedConstraint *Constraint)
: FoldExpanded{llvm::to_underlying(ConstraintKind::FoldExpanded),
llvm::to_underlying(OpKind),
/*Placeholder=*/0,
/*Indexes=*/{},
/*Args=*/nullptr,
Pattern,
Expand Down
45 changes: 30 additions & 15 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,11 @@ static std::optional<MultiLevelTemplateArgumentList>
SubstitutionInTemplateArguments(
Sema &S, const NormalizedConstraintWithParamMapping &Constraint,
const NamedDecl *Template, MultiLevelTemplateArgumentList MLTAL,
llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost) {
llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost,
// FIXME: Having both PackSubstitutionIndex and
// NormalizedConstraintWithParamMapping::getPackSubstitutionIndex is
// confusing
UnsignedOrNone PackSubstitutionIndex) {

Sema::InstantiatingTemplate Inst(
S, Constraint.getBeginLoc(),
Expand All @@ -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())
Expand Down Expand Up @@ -405,11 +411,12 @@ static bool calculateConstraintSatisfaction(
llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
std::optional<MultiLevelTemplateArgumentList> 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);
Expand Down Expand Up @@ -526,7 +533,8 @@ static bool calculateConstraintSatisfaction(
S,
static_cast<const NormalizedConstraintWithParamMapping &>(
FE.getNormalizedPattern()),
Template, MLTAL, SubstitutedOuterMost);
// FIXME: Is PackSubstitutionIndex correct?
Template, MLTAL, SubstitutedOuterMost, S.ArgPackSubstIndex);
if (!SubstitutedArgs)
return false;

Expand All @@ -548,14 +556,20 @@ 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,
Satisfaction.Details.end());
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;
}

Expand All @@ -569,11 +583,6 @@ static bool calculateConstraintSatisfaction(
S, Constraint.getConceptId()->getNamedConcept()->getDeclContext(),
/*NewThisContext=*/false);

llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
SubstitutionInTemplateArguments(S, Constraint, Template, MLTAL,
SubstitutedOuterMost);

Sema::InstantiatingTemplate Tpl(
S, Constraint.getConceptId()->getBeginLoc(),
Sema::InstantiatingTemplate::ConstraintsCheck{},
Expand All @@ -588,6 +597,12 @@ static bool calculateConstraintSatisfaction(

if (Size != Satisfaction.Details.size()) {

llvm::SmallVector<TemplateArgument> SubstitutedOuterMost;
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
SubstitutionInTemplateArguments(S, Constraint, Template, MLTAL,
SubstitutedOuterMost,
PackSubstitutionIndex);

if (!SubstitutedArgs)
return Ok;

Expand Down Expand Up @@ -633,7 +648,7 @@ static bool calculateConstraintSatisfaction(
SubstitutedConceptId.getAs<ConceptSpecializationExpr>()
->getConceptReference()));

Satisfaction.Details.push_back(nullptr);
// Satisfaction.Details.push_back(nullptr);
}
return Ok;
}
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions clang/test/SemaCXX/cxx2c-fold-exprs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ static_assert(And1<int, S>() == 1); // expected-error {{no matching function for

static_assert(And2<S>() == 2);
static_assert(And2<S, S>() == 2);
// FIXME: Should it compile??
static_assert(And2<int>() == 2);

static_assert(And2<int, int>() == 2); // expected-error {{no matching function for call to 'And2'}}
Expand Down