Fixed #5885 - fsanitize=undefined: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' in lib/tokenize.cpp.

This commit is contained in:
orbitcowboy 2014-05-29 18:25:01 +02:00
parent e9144d1a78
commit 60e80b6fb1
4 changed files with 35 additions and 17 deletions

View File

@ -539,6 +539,18 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon
return toString(d1 - d2); 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) std::string MathLib::divide(const std::string &first, const std::string &second)
{ {
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {

View File

@ -62,6 +62,7 @@ public:
static std::string multiply(const std::string & first, const std::string & second); 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 divide(const std::string & first, const std::string & second);
static std::string mod(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 calculate(const std::string & first, const std::string & second, char action);
static std::string sin(const std::string & tok); static std::string sin(const std::string & tok);

View File

@ -5198,21 +5198,6 @@ bool Tokenizer::simplifyFunctionReturn()
return ret; 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) void Tokenizer::simplifyVarDecl(bool only_k_r_fpar)
{ {
simplifyVarDecl(list.front(), nullptr, 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->varId(valueVarId);
tok3->deleteNext(); tok3->deleteNext();
} }
incdec(value, op); value = MathLib::incdec(value, op);
if (!Token::simpleMatch((*tok2)->tokAt(-2), "for (")) { if (!Token::simpleMatch((*tok2)->tokAt(-2), "for (")) {
(*tok2)->tokAt(2)->str(value); (*tok2)->tokAt(2)->str(value);
(*tok2)->tokAt(2)->varId(valueVarId); (*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) && if (indentlevel == indentlevel3 && Token::Match(tok3->next(), "++|-- %varid%", varid) && MathLib::isInt(value) &&
!Token::Match(tok3->tokAt(3), "[.[]")) { !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)->str(value);
(*tok2)->tokAt(2)->varId(valueVarId); (*tok2)->tokAt(2)->varId(valueVarId);
if (Token::Match(tok3, "[;{}] %any% %any% ;")) { if (Token::Match(tok3, "[;{}] %any% %any% ;")) {

View File

@ -47,6 +47,7 @@ private:
TEST_CASE(convert); TEST_CASE(convert);
TEST_CASE(naninf); TEST_CASE(naninf);
TEST_CASE(isNullValue); TEST_CASE(isNullValue);
TEST_CASE(incdec);
} }
void isGreater() const { void isGreater() const {
@ -781,6 +782,25 @@ private:
ASSERT_EQUALS(false, MathLib::isNullValue("garbage")); ASSERT_EQUALS(false, MathLib::isNullValue("garbage"));
ASSERT_EQUALS(false, MathLib::isNullValue("UL")); 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) REGISTER_TEST(TestMathLib)