diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 7140234dc..632dbc4cf 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -539,6 +539,18 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon return toString(d1 - d2); } +std::string MathLib::incdec(const std::string & var, const std::string & op) +{ + if (op == "++") + return MathLib::add(var, "1"); + else if (op == "--") + return MathLib::subtract(var, "1"); + + throw InternalError(0, std::string("Unexpected operation '") + op + "' in MathLib::incdec(). Please report this to Cppcheck developers."); + return ""; + +} + std::string MathLib::divide(const std::string &first, const std::string &second) { if (MathLib::isInt(first) && MathLib::isInt(second)) { diff --git a/lib/mathlib.h b/lib/mathlib.h index 35254a3af..740c94eb4 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -62,6 +62,7 @@ public: static std::string multiply(const std::string & first, const std::string & second); static std::string divide(const std::string & first, const std::string & second); static std::string mod(const std::string & first, const std::string & second); + static std::string incdec(const std::string & var, const std::string & op); static std::string calculate(const std::string & first, const std::string & second, char action); static std::string sin(const std::string & tok); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2fcd692a9..0fc183309 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5198,21 +5198,6 @@ bool Tokenizer::simplifyFunctionReturn() return ret; } - -static void incdec(std::string &value, const std::string &op) -{ - int ivalue = 0; - std::istringstream istr(value); - istr >> ivalue; - if (op == "++") - ++ivalue; - else if (op == "--") - --ivalue; - std::ostringstream ostr; - ostr << ivalue; - value = ostr.str(); -} - void Tokenizer::simplifyVarDecl(bool only_k_r_fpar) { simplifyVarDecl(list.front(), nullptr, only_k_r_fpar); @@ -6918,7 +6903,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign tok3->varId(valueVarId); tok3->deleteNext(); } - incdec(value, op); + value = MathLib::incdec(value, op); if (!Token::simpleMatch((*tok2)->tokAt(-2), "for (")) { (*tok2)->tokAt(2)->str(value); (*tok2)->tokAt(2)->varId(valueVarId); @@ -6928,7 +6913,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign if (indentlevel == indentlevel3 && Token::Match(tok3->next(), "++|-- %varid%", varid) && MathLib::isInt(value) && !Token::Match(tok3->tokAt(3), "[.[]")) { - incdec(value, tok3->next()->str()); + value = MathLib::incdec(value, tok3->next()->str()); (*tok2)->tokAt(2)->str(value); (*tok2)->tokAt(2)->varId(valueVarId); if (Token::Match(tok3, "[;{}] %any% %any% ;")) { diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index b0ee713c4..ec34b8a4b 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -47,6 +47,7 @@ private: TEST_CASE(convert); TEST_CASE(naninf); TEST_CASE(isNullValue); + TEST_CASE(incdec); } void isGreater() const { @@ -781,6 +782,25 @@ private: ASSERT_EQUALS(false, MathLib::isNullValue("garbage")); ASSERT_EQUALS(false, MathLib::isNullValue("UL")); } + + void incdec() { + // increment + { + MathLib::biguint num = ~10U; + const std::string op = "++"; + const std::string strNum = MathLib::incdec(MathLib::toString(num), op); + const MathLib::biguint incrementedNum = MathLib::toULongNumber(strNum); + ASSERT_EQUALS(num + 1U, incrementedNum); + } + // decrement + { + MathLib::biguint num = ~10U; + const std::string op = "--"; + const std::string strNum = MathLib::incdec(MathLib::toString(num), op); + const MathLib::biguint decrementedNum = MathLib::toULongNumber(strNum); + ASSERT_EQUALS(num - 1U, decrementedNum); + } + } }; REGISTER_TEST(TestMathLib)