diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index fb75a2f5a..488f75722 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -846,6 +846,11 @@ bool MathLib::isFloatHex(const std::string& str) return state==EXPONENT_DIGITS; } +bool MathLib::isValidIntegerSuffix(const std::string& str) +{ + return isValidIntegerSuffix(str.begin(), str.end()); +} + bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end) { enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64} state = START; @@ -1020,7 +1025,7 @@ bool MathLib::isInt(const std::string & str) return isDec(str) || isIntHex(str) || isOct(str) || isBin(str); } -static std::string getsuffix(const std::string& value) +std::string MathLib::getSuffix(const std::string& value) { if (value.size() > 3 && value[value.size() - 3] == 'i' && value[value.size() - 2] == '6' && value[value.size() - 1] == '4') { if (value[value.size() - 4] == 'u') @@ -1048,8 +1053,8 @@ static std::string getsuffix(const std::string& value) static std::string intsuffix(const std::string & first, const std::string & second) { - std::string suffix1 = getsuffix(first); - std::string suffix2 = getsuffix(second); + const std::string suffix1 = MathLib::getSuffix(first); + const std::string suffix2 = MathLib::getSuffix(second); if (suffix1 == "ULL" || suffix2 == "ULL") return "ULL"; if (suffix1 == "LL" || suffix2 == "LL") diff --git a/lib/mathlib.h b/lib/mathlib.h index fd6d16a07..33c4ed370 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -89,6 +89,8 @@ public: static bool isOct(const std::string& str); static bool isBin(const std::string& str); + static std::string getSuffix(const std::string& value); + static bool isValidIntegerSuffix(const std::string& str); static bool isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end); static std::string add(const std::string & first, const std::string & second); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 82619df64..55dddb2d8 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -129,12 +129,15 @@ void TokenList::addtoken(std::string str, const unsigned int lineno, const unsig } // Replace hexadecimal value with decimal - if (MathLib::isIntHex(str) || MathLib::isOct(str) || MathLib::isBin(str)) { + const bool isHex = MathLib::isIntHex(str) ; + if (isHex || MathLib::isOct(str) || MathLib::isBin(str)) { // TODO: It would be better if TokenList didn't simplify hexadecimal numbers std::string suffix; - if (str.compare(0,2,"0x") == 0 && + if (isHex && str.size() == (2 + _settings->int_bit / 4) && - (str[2] >= '8')) // includes A-F and a-f + (str[2] >= '8') && // includes A-F and a-f + MathLib::getSuffix(str).empty() + ) suffix = "U"; str = MathLib::value(str).str() + suffix; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0eb171137..10afdbb1a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -51,6 +51,7 @@ private: TEST_CASE(tokenize11); TEST_CASE(tokenize13); // bailout if the code contains "@" - that is not handled well. TEST_CASE(tokenize14); // tokenize "0X10" => 16 + TEST_CASE(tokenizeHexWithSuffix); // tokenize 0xFFFFFFul TEST_CASE(tokenize15); // tokenize ".123" TEST_CASE(tokenize17); // #2759 TEST_CASE(tokenize18); // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )" @@ -679,6 +680,18 @@ private: ASSERT_EQUALS("; 292 ;", tokenizeAndStringify(";0444;")); } + // Ticket #8050 + void tokenizeHexWithSuffix() { + ASSERT_EQUALS("; 16777215 ;", tokenizeAndStringify(";0xFFFFFF;")); + ASSERT_EQUALS("; 16777215U ;", tokenizeAndStringify(";0xFFFFFFu;")); + ASSERT_EQUALS("; 16777215UL ;", tokenizeAndStringify(";0xFFFFFFul;")); + + // Number of digits decides about internal representation... + ASSERT_EQUALS("; 4294967295U ;", tokenizeAndStringify(";0xFFFFFFFF;")); + ASSERT_EQUALS("; 4294967295U ;", tokenizeAndStringify(";0xFFFFFFFFu;")); + ASSERT_EQUALS("; 4294967295UL ;", tokenizeAndStringify(";0xFFFFFFFFul;")); + } + // Ticket #2429: 0.125 void tokenize15() { ASSERT_EQUALS("0.125 ;", tokenizeAndStringify(".125;"));