@@ -448,12 +448,12 @@ class EquivalenceClass : public llvm::FoldingSetNode {
448
448
EquivalenceClass Other);
449
449
450
450
// / Return a set of class members for the given state.
451
- LLVM_NODISCARD inline SymbolSet getClassMembers (ProgramStateRef State);
451
+ LLVM_NODISCARD inline SymbolSet getClassMembers (ProgramStateRef State) const ;
452
452
// / Return true if the current class is trivial in the given state.
453
- LLVM_NODISCARD inline bool isTrivial (ProgramStateRef State);
453
+ LLVM_NODISCARD inline bool isTrivial (ProgramStateRef State) const ;
454
454
// / Return true if the current class is trivial and its only member is dead.
455
455
LLVM_NODISCARD inline bool isTriviallyDead (ProgramStateRef State,
456
- SymbolReaper &Reaper);
456
+ SymbolReaper &Reaper) const ;
457
457
458
458
LLVM_NODISCARD static inline ProgramStateRef
459
459
markDisequal (BasicValueFactory &BV, RangeSet::Factory &F,
@@ -521,7 +521,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
521
521
ProgramStateRef State, SymbolSet Members,
522
522
EquivalenceClass Other,
523
523
SymbolSet OtherMembers);
524
- static inline void
524
+ static inline bool
525
525
addToDisequalityInfo (DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
526
526
BasicValueFactory &BV, RangeSet::Factory &F,
527
527
ProgramStateRef State, EquivalenceClass First,
@@ -535,6 +535,15 @@ class EquivalenceClass : public llvm::FoldingSetNode {
535
535
// Constraint functions
536
536
// ===----------------------------------------------------------------------===//
537
537
538
+ LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED bool
539
+ areFeasible (ConstraintRangeTy Constraints) {
540
+ return llvm::none_of (
541
+ Constraints,
542
+ [](const std::pair<EquivalenceClass, RangeSet> &ClassConstraint) {
543
+ return ClassConstraint.second .isEmpty ();
544
+ });
545
+ }
546
+
538
547
LLVM_NODISCARD inline const RangeSet *getConstraint (ProgramStateRef State,
539
548
EquivalenceClass Class) {
540
549
return State->get <ConstraintRange>(Class);
@@ -1397,15 +1406,6 @@ class RangeConstraintManager : public RangedConstraintManager {
1397
1406
return EquivalenceClass::merge (getBasicVals (), F, State, LHS, RHS);
1398
1407
}
1399
1408
1400
- LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
1401
- areFeasible (ConstraintRangeTy Constraints) {
1402
- return llvm::none_of (
1403
- Constraints,
1404
- [](const std::pair<EquivalenceClass, RangeSet> &ClassConstraint) {
1405
- return ClassConstraint.second .isEmpty ();
1406
- });
1407
- }
1408
-
1409
1409
LLVM_NODISCARD ProgramStateRef setConstraint (ProgramStateRef State,
1410
1410
EquivalenceClass Class,
1411
1411
RangeSet Constraint) {
@@ -1428,7 +1428,7 @@ class RangeConstraintManager : public RangedConstraintManager {
1428
1428
getRange (State, DisequalClass).Delete (getBasicVals (), F, *Point );
1429
1429
1430
1430
// If we end up with at least one of the disequal classes to be
1431
- // constrainted with an empty range-set, the state is infeasible.
1431
+ // constrained with an empty range-set, the state is infeasible.
1432
1432
if (UpdatedConstraint.isEmpty ())
1433
1433
return nullptr ;
1434
1434
@@ -1574,6 +1574,9 @@ EquivalenceClass::mergeImpl(BasicValueFactory &ValueFactory,
1574
1574
// Assign new constraints for this class.
1575
1575
Constraints = CRF.add (Constraints, *this , *NewClassConstraint);
1576
1576
1577
+ assert (areFeasible (Constraints) && " Constraint manager shouldn't produce "
1578
+ " a state with infeasible constraints" );
1579
+
1577
1580
State = State->set <ConstraintRange>(Constraints);
1578
1581
}
1579
1582
@@ -1644,7 +1647,7 @@ EquivalenceClass::getMembersFactory(ProgramStateRef State) {
1644
1647
return State->get_context <SymbolSet>();
1645
1648
}
1646
1649
1647
- SymbolSet EquivalenceClass::getClassMembers (ProgramStateRef State) {
1650
+ SymbolSet EquivalenceClass::getClassMembers (ProgramStateRef State) const {
1648
1651
if (const SymbolSet *Members = State->get <ClassMembers>(*this ))
1649
1652
return *Members;
1650
1653
@@ -1654,12 +1657,12 @@ SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) {
1654
1657
return F.add (F.getEmptySet (), getRepresentativeSymbol ());
1655
1658
}
1656
1659
1657
- bool EquivalenceClass::isTrivial (ProgramStateRef State) {
1660
+ bool EquivalenceClass::isTrivial (ProgramStateRef State) const {
1658
1661
return State->get <ClassMembers>(*this ) == nullptr ;
1659
1662
}
1660
1663
1661
1664
bool EquivalenceClass::isTriviallyDead (ProgramStateRef State,
1662
- SymbolReaper &Reaper) {
1665
+ SymbolReaper &Reaper) const {
1663
1666
return isTrivial (State) && Reaper.isDead (getRepresentativeSymbol ());
1664
1667
}
1665
1668
@@ -1694,18 +1697,22 @@ EquivalenceClass::markDisequal(BasicValueFactory &VF, RangeSet::Factory &RF,
1694
1697
1695
1698
// Disequality is a symmetric relation, so if we mark A as disequal to B,
1696
1699
// we should also mark B as disequalt to A.
1697
- addToDisequalityInfo (DisequalityInfo, Constraints, VF, RF, State, *this ,
1698
- Other);
1699
- addToDisequalityInfo (DisequalityInfo, Constraints, VF, RF, State, Other,
1700
- *this );
1700
+ if (!addToDisequalityInfo (DisequalityInfo, Constraints, VF, RF, State, *this ,
1701
+ Other) ||
1702
+ !addToDisequalityInfo (DisequalityInfo, Constraints, VF, RF, State, Other,
1703
+ *this ))
1704
+ return nullptr ;
1705
+
1706
+ assert (areFeasible (Constraints) && " Constraint manager shouldn't produce "
1707
+ " a state with infeasible constraints" );
1701
1708
1702
1709
State = State->set <DisequalityMap>(DisequalityInfo);
1703
1710
State = State->set <ConstraintRange>(Constraints);
1704
1711
1705
1712
return State;
1706
1713
}
1707
1714
1708
- inline void EquivalenceClass::addToDisequalityInfo (
1715
+ inline bool EquivalenceClass::addToDisequalityInfo (
1709
1716
DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
1710
1717
BasicValueFactory &VF, RangeSet::Factory &RF, ProgramStateRef State,
1711
1718
EquivalenceClass First, EquivalenceClass Second) {
@@ -1734,8 +1741,16 @@ inline void EquivalenceClass::addToDisequalityInfo(
1734
1741
VF, RF, State, First.getRepresentativeSymbol ());
1735
1742
1736
1743
FirstConstraint = FirstConstraint.Delete (VF, RF, *Point );
1744
+
1745
+ // If the First class is about to be constrained with an empty
1746
+ // range-set, the state is infeasible.
1747
+ if (FirstConstraint.isEmpty ())
1748
+ return false ;
1749
+
1737
1750
Constraints = CRF.add (Constraints, First, FirstConstraint);
1738
1751
}
1752
+
1753
+ return true ;
1739
1754
}
1740
1755
1741
1756
inline Optional<bool > EquivalenceClass::areEqual (ProgramStateRef State,
0 commit comments