@@ -448,12 +448,12 @@ class EquivalenceClass : public llvm::FoldingSetNode {
448448 EquivalenceClass Other);
449449
450450 // / 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 ;
452452 // / 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 ;
454454 // / Return true if the current class is trivial and its only member is dead.
455455 LLVM_NODISCARD inline bool isTriviallyDead (ProgramStateRef State,
456- SymbolReaper &Reaper);
456+ SymbolReaper &Reaper) const ;
457457
458458 LLVM_NODISCARD static inline ProgramStateRef
459459 markDisequal (BasicValueFactory &BV, RangeSet::Factory &F,
@@ -521,7 +521,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
521521 ProgramStateRef State, SymbolSet Members,
522522 EquivalenceClass Other,
523523 SymbolSet OtherMembers);
524- static inline void
524+ static inline bool
525525 addToDisequalityInfo (DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
526526 BasicValueFactory &BV, RangeSet::Factory &F,
527527 ProgramStateRef State, EquivalenceClass First,
@@ -535,6 +535,15 @@ class EquivalenceClass : public llvm::FoldingSetNode {
535535// Constraint functions
536536// ===----------------------------------------------------------------------===//
537537
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+
538547LLVM_NODISCARD inline const RangeSet *getConstraint (ProgramStateRef State,
539548 EquivalenceClass Class) {
540549 return State->get <ConstraintRange>(Class);
@@ -1397,15 +1406,6 @@ class RangeConstraintManager : public RangedConstraintManager {
13971406 return EquivalenceClass::merge (getBasicVals (), F, State, LHS, RHS);
13981407 }
13991408
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-
14091409 LLVM_NODISCARD ProgramStateRef setConstraint (ProgramStateRef State,
14101410 EquivalenceClass Class,
14111411 RangeSet Constraint) {
@@ -1428,7 +1428,7 @@ class RangeConstraintManager : public RangedConstraintManager {
14281428 getRange (State, DisequalClass).Delete (getBasicVals (), F, *Point);
14291429
14301430 // 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.
14321432 if (UpdatedConstraint.isEmpty ())
14331433 return nullptr ;
14341434
@@ -1574,6 +1574,9 @@ EquivalenceClass::mergeImpl(BasicValueFactory &ValueFactory,
15741574 // Assign new constraints for this class.
15751575 Constraints = CRF.add (Constraints, *this , *NewClassConstraint);
15761576
1577+ assert (areFeasible (Constraints) && " Constraint manager shouldn't produce "
1578+ " a state with infeasible constraints" );
1579+
15771580 State = State->set <ConstraintRange>(Constraints);
15781581 }
15791582
@@ -1644,7 +1647,7 @@ EquivalenceClass::getMembersFactory(ProgramStateRef State) {
16441647 return State->get_context <SymbolSet>();
16451648}
16461649
1647- SymbolSet EquivalenceClass::getClassMembers (ProgramStateRef State) {
1650+ SymbolSet EquivalenceClass::getClassMembers (ProgramStateRef State) const {
16481651 if (const SymbolSet *Members = State->get <ClassMembers>(*this ))
16491652 return *Members;
16501653
@@ -1654,12 +1657,12 @@ SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) {
16541657 return F.add (F.getEmptySet (), getRepresentativeSymbol ());
16551658}
16561659
1657- bool EquivalenceClass::isTrivial (ProgramStateRef State) {
1660+ bool EquivalenceClass::isTrivial (ProgramStateRef State) const {
16581661 return State->get <ClassMembers>(*this ) == nullptr ;
16591662}
16601663
16611664bool EquivalenceClass::isTriviallyDead (ProgramStateRef State,
1662- SymbolReaper &Reaper) {
1665+ SymbolReaper &Reaper) const {
16631666 return isTrivial (State) && Reaper.isDead (getRepresentativeSymbol ());
16641667}
16651668
@@ -1694,18 +1697,22 @@ EquivalenceClass::markDisequal(BasicValueFactory &VF, RangeSet::Factory &RF,
16941697
16951698 // Disequality is a symmetric relation, so if we mark A as disequal to B,
16961699 // 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" );
17011708
17021709 State = State->set <DisequalityMap>(DisequalityInfo);
17031710 State = State->set <ConstraintRange>(Constraints);
17041711
17051712 return State;
17061713}
17071714
1708- inline void EquivalenceClass::addToDisequalityInfo (
1715+ inline bool EquivalenceClass::addToDisequalityInfo (
17091716 DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
17101717 BasicValueFactory &VF, RangeSet::Factory &RF, ProgramStateRef State,
17111718 EquivalenceClass First, EquivalenceClass Second) {
@@ -1734,8 +1741,16 @@ inline void EquivalenceClass::addToDisequalityInfo(
17341741 VF, RF, State, First.getRepresentativeSymbol ());
17351742
17361743 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+
17371750 Constraints = CRF.add (Constraints, First, FirstConstraint);
17381751 }
1752+
1753+ return true ;
17391754}
17401755
17411756inline Optional<bool > EquivalenceClass::areEqual (ProgramStateRef State,
0 commit comments