@@ -1249,6 +1249,8 @@ class SymbolicRangeInferrer
12491249 // calculate the effective range set by intersecting the range set
12501250 // for A - B and the negated range set of B - A.
12511251 getRangeForNegatedSymSym (SSE),
1252+ // If commutative, we may have constaints for the commuted variant.
1253+ getRangeCommutativeSymSym (SSE),
12521254 // If Sym is a comparison expression (except <=>),
12531255 // find any other comparisons with the same operands.
12541256 // See function description.
@@ -1485,6 +1487,21 @@ class SymbolicRangeInferrer
14851487 Sym->getType ());
14861488 }
14871489
1490+ std::optional<RangeSet> getRangeCommutativeSymSym (const SymSymExpr *SSE) {
1491+ auto Op = SSE->getOpcode ();
1492+ bool IsCommutative = llvm::is_contained (
1493+ // ==, !=, |, &, +, *, ^
1494+ {BO_EQ, BO_NE, BO_Or, BO_And, BO_Add, BO_Mul, BO_Xor}, Op);
1495+ if (!IsCommutative)
1496+ return std::nullopt ;
1497+
1498+ SymbolRef Commuted = State->getSymbolManager ().getSymSymExpr (
1499+ SSE->getRHS (), Op, SSE->getLHS (), SSE->getType ());
1500+ if (const RangeSet *Range = getConstraint (State, Commuted))
1501+ return *Range;
1502+ return std::nullopt ;
1503+ }
1504+
14881505 // Returns ranges only for binary comparison operators (except <=>)
14891506 // when left and right operands are symbolic values.
14901507 // Finds any other comparisons with the same operands.
@@ -1936,27 +1953,27 @@ class RangeConstraintManager : public RangedConstraintManager {
19361953 const llvm::APSInt &To, const llvm::APSInt &Adjustment) override ;
19371954
19381955private:
1939- RangeSet::Factory F;
1956+ mutable RangeSet::Factory F;
19401957
1941- RangeSet getRange (ProgramStateRef State, SymbolRef Sym);
1958+ RangeSet getRange (ProgramStateRef State, SymbolRef Sym) const ;
19421959 ProgramStateRef setRange (ProgramStateRef State, SymbolRef Sym,
19431960 RangeSet Range);
19441961
19451962 RangeSet getSymLTRange (ProgramStateRef St, SymbolRef Sym,
19461963 const llvm::APSInt &Int,
1947- const llvm::APSInt &Adjustment);
1964+ const llvm::APSInt &Adjustment) const ;
19481965 RangeSet getSymGTRange (ProgramStateRef St, SymbolRef Sym,
19491966 const llvm::APSInt &Int,
1950- const llvm::APSInt &Adjustment);
1967+ const llvm::APSInt &Adjustment) const ;
19511968 RangeSet getSymLERange (ProgramStateRef St, SymbolRef Sym,
19521969 const llvm::APSInt &Int,
1953- const llvm::APSInt &Adjustment);
1970+ const llvm::APSInt &Adjustment) const ;
19541971 RangeSet getSymLERange (llvm::function_ref<RangeSet()> RS,
19551972 const llvm::APSInt &Int,
1956- const llvm::APSInt &Adjustment);
1973+ const llvm::APSInt &Adjustment) const ;
19571974 RangeSet getSymGERange (ProgramStateRef St, SymbolRef Sym,
19581975 const llvm::APSInt &Int,
1959- const llvm::APSInt &Adjustment);
1976+ const llvm::APSInt &Adjustment) const ;
19601977};
19611978
19621979// ===----------------------------------------------------------------------===//
@@ -2863,21 +2880,18 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
28632880
28642881const llvm::APSInt *RangeConstraintManager::getSymVal (ProgramStateRef St,
28652882 SymbolRef Sym) const {
2866- auto &MutableSelf = const_cast <RangeConstraintManager &>(*this );
2867- return MutableSelf.getRange (St, Sym).getConcreteValue ();
2883+ return getRange (St, Sym).getConcreteValue ();
28682884}
28692885
28702886const llvm::APSInt *RangeConstraintManager::getSymMinVal (ProgramStateRef St,
28712887 SymbolRef Sym) const {
2872- auto &MutableSelf = const_cast <RangeConstraintManager &>(*this );
2873- RangeSet Range = MutableSelf.getRange (St, Sym);
2888+ RangeSet Range = getRange (St, Sym);
28742889 return Range.isEmpty () ? nullptr : &Range.getMinValue ();
28752890}
28762891
28772892const llvm::APSInt *RangeConstraintManager::getSymMaxVal (ProgramStateRef St,
28782893 SymbolRef Sym) const {
2879- auto &MutableSelf = const_cast <RangeConstraintManager &>(*this );
2880- RangeSet Range = MutableSelf.getRange (St, Sym);
2894+ RangeSet Range = getRange (St, Sym);
28812895 return Range.isEmpty () ? nullptr : &Range.getMaxValue ();
28822896}
28832897
@@ -3022,7 +3036,7 @@ RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
30223036}
30233037
30243038RangeSet RangeConstraintManager::getRange (ProgramStateRef State,
3025- SymbolRef Sym) {
3039+ SymbolRef Sym) const {
30263040 return SymbolicRangeInferrer::inferRange (F, State, Sym);
30273041}
30283042
@@ -3077,10 +3091,10 @@ RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
30773091 return setRange (St, Sym, New);
30783092}
30793093
3080- RangeSet RangeConstraintManager::getSymLTRange (ProgramStateRef St,
3081- SymbolRef Sym,
3082- const llvm::APSInt &Int,
3083- const llvm::APSInt &Adjustment) {
3094+ RangeSet
3095+ RangeConstraintManager::getSymLTRange (ProgramStateRef St, SymbolRef Sym,
3096+ const llvm::APSInt &Int,
3097+ const llvm::APSInt &Adjustment) const {
30843098 // Before we do any real work, see if the value can even show up.
30853099 APSIntType AdjustmentType (Adjustment);
30863100 switch (AdjustmentType.testInRange (Int, true )) {
@@ -3114,10 +3128,10 @@ RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
31143128 return setRange (St, Sym, New);
31153129}
31163130
3117- RangeSet RangeConstraintManager::getSymGTRange (ProgramStateRef St,
3118- SymbolRef Sym,
3119- const llvm::APSInt &Int,
3120- const llvm::APSInt &Adjustment) {
3131+ RangeSet
3132+ RangeConstraintManager::getSymGTRange (ProgramStateRef St, SymbolRef Sym,
3133+ const llvm::APSInt &Int,
3134+ const llvm::APSInt &Adjustment) const {
31213135 // Before we do any real work, see if the value can even show up.
31223136 APSIntType AdjustmentType (Adjustment);
31233137 switch (AdjustmentType.testInRange (Int, true )) {
@@ -3151,10 +3165,10 @@ RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
31513165 return setRange (St, Sym, New);
31523166}
31533167
3154- RangeSet RangeConstraintManager::getSymGERange (ProgramStateRef St,
3155- SymbolRef Sym,
3156- const llvm::APSInt &Int,
3157- const llvm::APSInt &Adjustment) {
3168+ RangeSet
3169+ RangeConstraintManager::getSymGERange (ProgramStateRef St, SymbolRef Sym,
3170+ const llvm::APSInt &Int,
3171+ const llvm::APSInt &Adjustment) const {
31583172 // Before we do any real work, see if the value can even show up.
31593173 APSIntType AdjustmentType (Adjustment);
31603174 switch (AdjustmentType.testInRange (Int, true )) {
@@ -3191,7 +3205,7 @@ RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
31913205RangeSet
31923206RangeConstraintManager::getSymLERange (llvm::function_ref<RangeSet()> RS,
31933207 const llvm::APSInt &Int,
3194- const llvm::APSInt &Adjustment) {
3208+ const llvm::APSInt &Adjustment) const {
31953209 // Before we do any real work, see if the value can even show up.
31963210 APSIntType AdjustmentType (Adjustment);
31973211 switch (AdjustmentType.testInRange (Int, true )) {
@@ -3217,10 +3231,10 @@ RangeConstraintManager::getSymLERange(llvm::function_ref<RangeSet()> RS,
32173231 return F.intersect (Default, Lower, Upper);
32183232}
32193233
3220- RangeSet RangeConstraintManager::getSymLERange (ProgramStateRef St,
3221- SymbolRef Sym,
3222- const llvm::APSInt &Int,
3223- const llvm::APSInt &Adjustment) {
3234+ RangeSet
3235+ RangeConstraintManager::getSymLERange (ProgramStateRef St, SymbolRef Sym,
3236+ const llvm::APSInt &Int,
3237+ const llvm::APSInt &Adjustment) const {
32243238 return getSymLERange ([&] { return getRange (St, Sym); }, Int, Adjustment);
32253239}
32263240
0 commit comments