@@ -1807,21 +1807,31 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
18071807 return commutativeEquals;
18081808}
18091809
1810- static bool isZeroBoundCond (const Token * const cond)
1810+ static bool isZeroBoundCond (const Token * const cond, bool reverse )
18111811{
1812- if (cond == nullptr )
1812+ if (cond == nullptr || !cond-> isBinaryOp () )
18131813 return false ;
1814+
1815+ const Token* op = reverse ? cond->astOperand1 () : cond->astOperand2 ();
1816+ if (!op->hasKnownIntValue ())
1817+ return false ;
1818+
18141819 // Assume unsigned
1815- // TODO: Handle reverse conditions
1816- const bool isZero = cond->astOperand2 ()->getValue (0 );
1817- if (cond->str () == " ==" || cond->str () == " >=" )
1820+ const bool isZero = op->getKnownIntValue () == 0 ;
1821+ std::string cmp = cond->str ();
1822+ if (reverse) {
1823+ if (cmp[0 ] == ' >' )
1824+ cmp[0 ] = ' <' ;
1825+ else if (cmp[0 ] == ' <' )
1826+ cmp[0 ] = ' >' ;
1827+ }
1828+
1829+ if (cmp == " ==" || cmp == " >=" )
18181830 return isZero;
1819- if (cond-> str () == " <=" )
1831+ if (cmp == " <=" )
18201832 return true ;
1821- if (cond-> str () == " <" )
1833+ if (cmp == " <" )
18221834 return !isZero;
1823- if (cond->str () == " >" )
1824- return false ;
18251835 return false ;
18261836}
18271837
@@ -1885,7 +1895,7 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c
18851895 if (isSameExpression (true , cond1->astOperand2 (), cond2->astOperand2 (), settings, pure, followVar, errors))
18861896 return isDifferentKnownValues (cond1->astOperand1 (), cond2->astOperand1 ());
18871897 }
1888- // TODO: Handle reverse conditions
1898+
18891899 if (Library::isContainerYield (cond1, Library::Container::Yield::EMPTY, " empty" ) &&
18901900 Library::isContainerYield (cond2->astOperand1 (), Library::Container::Yield::SIZE, " size" ) &&
18911901 isSameExpression (true ,
@@ -1895,7 +1905,19 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c
18951905 pure,
18961906 followVar,
18971907 errors)) {
1898- return !isZeroBoundCond (cond2);
1908+ return !isZeroBoundCond (cond2, false );
1909+ }
1910+
1911+ if (Library::isContainerYield (cond1, Library::Container::Yield::EMPTY, " empty" ) &&
1912+ Library::isContainerYield (cond2->astOperand2 (), Library::Container::Yield::SIZE, " size" ) &&
1913+ isSameExpression (true ,
1914+ cond1->astOperand1 ()->astOperand1 (),
1915+ cond2->astOperand2 ()->astOperand1 ()->astOperand1 (),
1916+ settings,
1917+ pure,
1918+ followVar,
1919+ errors)) {
1920+ return !isZeroBoundCond (cond2, true );
18991921 }
19001922
19011923 if (Library::isContainerYield (cond2, Library::Container::Yield::EMPTY, " empty" ) &&
@@ -1907,7 +1929,19 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c
19071929 pure,
19081930 followVar,
19091931 errors)) {
1910- return !isZeroBoundCond (cond1);
1932+ return !isZeroBoundCond (cond1, false );
1933+ }
1934+
1935+ if (Library::isContainerYield (cond2, Library::Container::Yield::EMPTY, " empty" ) &&
1936+ Library::isContainerYield (cond1->astOperand2 (), Library::Container::Yield::SIZE, " size" ) &&
1937+ isSameExpression (true ,
1938+ cond2->astOperand1 ()->astOperand1 (),
1939+ cond1->astOperand2 ()->astOperand1 ()->astOperand1 (),
1940+ settings,
1941+ pure,
1942+ followVar,
1943+ errors)) {
1944+ return !isZeroBoundCond (cond1, true );
19111945 }
19121946 }
19131947
0 commit comments