Skip to content

Commit 19c301d

Browse files
committed
fix compouund constraint checking
1 parent 1cce903 commit 19c301d

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

clang/lib/Sema/SemaConcept.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,7 @@ static bool calculateConstraintSatisfaction(
550550
if (!Success)
551551
return false;
552552
if (!Conjunction && Satisfaction.IsSatisfied) {
553-
auto EffectiveDetailEnd = Satisfaction.Details.begin();
554-
std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
555-
Satisfaction.Details.erase(EffectiveDetailEnd,
553+
Satisfaction.Details.erase(Satisfaction.Details.begin() + EffectiveDetailEndIndex,
556554
Satisfaction.Details.end());
557555
break;
558556
}
@@ -635,24 +633,34 @@ static bool calculateConstraintSatisfaction(
635633
ConstraintSatisfaction &Satisfaction,
636634
UnsignedOrNone PackSubstitutionIndex) {
637635

636+
auto EffectiveDetailEndIndex = Satisfaction.Details.size();
637+
638638
bool Ok = calculateConstraintSatisfaction(
639639
S, Constraint.getLHS(), Template, TemplateNameLoc, MLTAL, Satisfaction,
640640
PackSubstitutionIndex);
641641

642642
if (!Ok || Satisfaction.ContainsErrors)
643-
return false;
643+
return Ok;
644644

645645
if (Satisfaction.IsSatisfied &&
646646
Constraint.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) {
647647
return true;
648648
}
649649
if (!Satisfaction.IsSatisfied &&
650-
Constraint.getCompoundKind() == NormalizedConstraint::CCK_Conjunction)
650+
Constraint.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) {
651651
return true;
652+
}
652653

653-
return calculateConstraintSatisfaction(S, Constraint.getRHS(), Template,
654+
Satisfaction.ContainsErrors = false;
655+
Satisfaction.IsSatisfied = false;
656+
657+
Ok = calculateConstraintSatisfaction(S, Constraint.getRHS(), Template,
654658
TemplateNameLoc, MLTAL, Satisfaction,
655659
PackSubstitutionIndex);
660+
if(Ok && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors)
661+
Satisfaction.Details.erase(Satisfaction.Details.begin() + EffectiveDetailEndIndex,
662+
Satisfaction.Details.end());
663+
return Ok;
656664
}
657665

658666
static bool calculateConstraintSatisfaction(
@@ -1349,6 +1357,7 @@ static void diagnoseUnsatisfiedRequirement(Sema &S,
13491357
concepts::NestedRequirement *Req,
13501358
bool First) {
13511359
DiagnoseUnsatisfiedConstraint(S, Req->getConstraintSatisfaction().records(),
1360+
Req->hasInvalidConstraint() ? SourceLocation() :
13521361
Req->getConstraintExpr()->getExprLoc(), First,
13531362
Req);
13541363
}

clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ concept C7 = sizeof(T) == 1 || sizeof(
141141

142142
static_assert(!C6<short>);
143143
static_assert(!C6<char>);
144-
// expected-error@-1 {{static assertion failed due to requirement '!C6<char>'}} \
145144
// expected-note@-1 {{while checking the satisfaction of concept 'C6<char>' requested here}}
146145
static_assert(C7<char>);
147146
static_assert(!C7<short>); // expected-note{{while checking the satisfaction of concept 'C7<short>' requested here}}

clang/test/SemaTemplate/concepts.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,13 +1000,13 @@ template<class>
10001000
concept True = true;
10011001

10021002
template<class>
1003-
concept False = false; // expected-note 9 {{'false' evaluated to false}}
1003+
concept False = false; // expected-note 8 {{'false' evaluated to false}}
10041004

10051005
template<class>
10061006
concept Irrelevant = false;
10071007

10081008
template <typename T>
1009-
concept ErrorRequires = requires(ErrorRequires auto x) { x; };
1009+
concept ErrorRequires = requires(ErrorRequires auto x) { x; }; //#GH54678-ill-formed-concept
10101010
// expected-error@-1 {{a concept definition cannot refer to itself}} \
10111011
// expected-error@-1 {{'auto' not allowed in requires expression parameter}} \
10121012
// expected-note@-1 {{declared here}}
@@ -1027,7 +1027,8 @@ template<class T> void eee(T t) // expected-note {{candidate template ignored: c
10271027
requires (Irrelevant<T> || Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'long' does not satisfy 'False'}}
10281028

10291029
template<class T> void fff(T t) // expected-note {{candidate template ignored: constraints not satisfied}}
1030-
requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} // expected-note {{'unsigned long' does not satisfy 'False'}}
1030+
requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} // expected-note {{because 'unsigned long' does not satisfy 'ErrorRequires'}}
1031+
// // expected-note@#GH54678-ill-formed-concept {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
10311032

10321033
void test() {
10331034
aaa(42); // expected-error {{no matching function}}

0 commit comments

Comments
 (0)