diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 469ff75d0..915246810 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -605,7 +605,7 @@ private: if (Token::Match(tok.tokAt(6), "%num% )")) { const unsigned int len = Token::getStrLength(tok.tokAt(4)); - const long sz = MathLib::toLongNumber(tok.strAt(6)); + const MathLib::bigint sz = MathLib::toLongNumber(tok.strAt(6)); if (sz >= 0 && len >= static_cast(sz)) { init_strncpy(checks, tok.tokAt(2)); diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 57c9ad05c..22c04c0e3 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -30,23 +30,37 @@ #include #include -long MathLib::toLongNumber(const std::string &str) +MathLib::bigint MathLib::toLongNumber(const std::string &str) { + // hexadecimal numbers: if (str.compare(0, 2, "0x") == 0 || str.compare(0, 3, "+0x") == 0 || str.compare(0, 3, "-0x") == 0) { - return std::strtol(str.c_str(), '\0', 16); + bigint ret = 0; + std::istringstream istr(str.substr((str[0]=='0') ? 2 : 3)); + istr >> std::hex >> ret; + return (str[0]=='-') ? -ret : ret; } + + // octal numbers: if (str.compare(0, 1, "0") == 0 || str.compare(0, 2, "+0") == 0 || str.compare(0, 2, "-0") == 0) { - return std::strtol(str.c_str(), '\0', 8); + bigint ret = 0; + std::istringstream istr(str.substr((str[0]=='0') ? 1 : 2)); + istr >> std::oct >> ret; + return (str[0]=='-') ? -ret : ret; } - return (str.find("E", 0) != std::string::npos || str.find("e", 0) != std::string::npos) - ? static_cast(std::atof(str.c_str())) - : std::atol(str.c_str()); + + if (str.find_first_of("eE") != std::string::npos) + return static_cast(std::atof(str.c_str())); + + bigint ret = 0; + std::istringstream istr(str); + istr >> ret; + return ret; } double MathLib::toDoubleNumber(const std::string &str) @@ -199,7 +213,7 @@ std::string MathLib::add(const std::string & first, const std::string & second) { if (MathLib::isInt(first) && MathLib::isInt(second)) { - return toString(toLongNumber(first) + toLongNumber(second)); + return toString(toLongNumber(first) + toLongNumber(second)); } return toString(toDoubleNumber(first) + toDoubleNumber(second)); } @@ -208,7 +222,7 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon { if (MathLib::isInt(first) && MathLib::isInt(second)) { - return toString(toLongNumber(first) - toLongNumber(second)); + return toString(toLongNumber(first) - toLongNumber(second)); } return toString(toDoubleNumber(first) - toDoubleNumber(second)); } @@ -217,7 +231,7 @@ std::string MathLib::divide(const std::string &first, const std::string &second) { if (MathLib::isInt(first) && MathLib::isInt(second)) { - return toString(toLongNumber(first) / toLongNumber(second)); + return toString(toLongNumber(first) / toLongNumber(second)); } return toString(toDoubleNumber(first) / toDoubleNumber(second)); } @@ -226,7 +240,7 @@ std::string MathLib::multiply(const std::string &first, const std::string &secon { if (MathLib::isInt(first) && MathLib::isInt(second)) { - return toString(toLongNumber(first) * toLongNumber(second)); + return toString(toLongNumber(first) * toLongNumber(second)); } return toString(toDoubleNumber(first) * toDoubleNumber(second)); } diff --git a/lib/mathlib.h b/lib/mathlib.h index 1ff4f6ccd..717dd6116 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -33,7 +33,16 @@ class Tokenizer; class MathLib { public: - static long toLongNumber(const std::string & str); + // To compile Cppcheck on a compiler that doesn't support "long long", + // use NOLONGLONG. +#ifdef NOLONGLONG + typedef long bigint; +#else + typedef long long bigint; +#endif + + + static bigint toLongNumber(const std::string & str); static double toDoubleNumber(const std::string & str); template diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ef0f9f5e4..3bce12c26 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6571,9 +6571,9 @@ bool Tokenizer::simplifyCalculations() const std::string after(tok->tokAt(3) ? tok->strAt(3).c_str() : ""); if ((prev == "(" || prev == "&&" || prev == "||") && (after == ")" || after == "&&" || after == "||")) { - const int op1(MathLib::toLongNumber(tok->str())); + const MathLib::bigint op1(MathLib::toLongNumber(tok->str())); const std::string &cmp(tok->next()->str()); - const int op2(MathLib::toLongNumber(tok->tokAt(2)->str())); + const MathLib::bigint op2(MathLib::toLongNumber(tok->tokAt(2)->str())); std::string result; @@ -6598,16 +6598,16 @@ bool Tokenizer::simplifyCalculations() if (Token::Match(tok->previous(), "[([,=] %num% <<|>> %num%")) { - const int op1(MathLib::toLongNumber(tok->str())); - const int op2(MathLib::toLongNumber(tok->tokAt(2)->str())); - int result; + const MathLib::bigint op1(MathLib::toLongNumber(tok->str())); + const MathLib::bigint op2(MathLib::toLongNumber(tok->tokAt(2)->str())); + MathLib::bigint result; if (tok->next()->str() == "<<") result = op1 << op2; else result = op1 >> op2; - std::stringstream ss; + std::ostringstream ss; ss << result; tok->str(ss.str()); @@ -7091,7 +7091,7 @@ void Tokenizer::simplifyEnum() end = tok1->tokAt(-1)->link(); - long lastValue = -1; + MathLib::bigint lastValue = -1; Token * lastEnumValueStart = 0; Token * lastEnumValueEnd = 0; @@ -7146,7 +7146,7 @@ void Tokenizer::simplifyEnum() // value is previous expression + 1 tok1->insertToken("+"); tok1 = tok1->next(); - tok1->insertToken(MathLib::toString(lastValue)); + tok1->insertToken(MathLib::toString(lastValue)); enumValue = 0; enumValueStart = valueStart->next(); enumValueEnd = tok1->next(); @@ -7154,7 +7154,7 @@ void Tokenizer::simplifyEnum() else { // value is previous numeric value + 1 - tok1->insertToken(MathLib::toString(lastValue)); + tok1->insertToken(MathLib::toString(lastValue)); enumValue = tok1->next(); } } diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 55908f432..03086c227 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -68,7 +68,7 @@ private: ASSERT_EQUALS("-3000" , MathLib::multiply("-1.0E+3", "3")); ASSERT_EQUALS("0" , MathLib::multiply("-1.0E+3", "0")); ASSERT_EQUALS("0" , MathLib::multiply("+1.0E+3", "0")); - TODO_ASSERT_EQUALS("2147483648" , MathLib::multiply("2","1073741824")); + ASSERT_EQUALS("2147483648" , MathLib::multiply("2","1073741824")); ASSERT_EQUALS("536870912" , MathLib::multiply("512","1048576")); // divide