Skip to content

Commit f6e7fb4

Browse files
Bugfix valuetype for some integer constants (danmar#2545)
1 parent 95ac456 commit f6e7fb4

14 files changed

+117
-103
lines changed

lib/checkfunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ void CheckFunctions::memsetZeroBytes()
328328
if (WRONG_DATA(arguments.size() != 3U, tok))
329329
continue;
330330
const Token* lastParamTok = arguments[2];
331-
if (lastParamTok->str() == "0")
331+
if (MathLib::isNullValue(lastParamTok->str()))
332332
memsetZeroBytesError(tok);
333333
}
334334
}

lib/mathlib.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,9 @@ std::string MathLib::tan(const std::string &tok)
12931293

12941294
std::string MathLib::abs(const std::string &tok)
12951295
{
1296-
return toString(std::abs(toDoubleNumber(tok)));
1296+
if (isNegative(tok))
1297+
return tok.substr(1, tok.length() - 1);
1298+
return tok;
12971299
}
12981300

12991301
bool MathLib::isEqual(const std::string &first, const std::string &second)

lib/platform.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,22 @@ namespace cppcheck {
6060
return value >= min_value(int_bit) && value <= max_value(int_bit);
6161
}
6262

63+
bool isIntValue(unsigned long long value) const {
64+
return value <= max_value(int_bit);
65+
}
66+
6367
bool isLongValue(long long value) const {
6468
return value >= min_value(long_bit) && value <= max_value(long_bit);
6569
}
6670

71+
bool isLongValue(unsigned long long value) const {
72+
return value <= max_value(long_bit);
73+
}
74+
75+
bool isLongLongValue(unsigned long long value) const {
76+
return value <= max_value(long_long_bit);
77+
}
78+
6779
nonneg int char_bit; /// bits in char
6880
nonneg int short_bit; /// bits in short
6981
nonneg int int_bit; /// bits in int

lib/symboldatabase.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5752,31 +5752,41 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings)
57525752
type = ValueType::Type::LONGDOUBLE;
57535753
setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, type, 0U));
57545754
} else if (MathLib::isInt(tok->str())) {
5755-
const bool unsignedSuffix = (tok->str().find_last_of("uU") != std::string::npos);
5755+
const std::string tokStr = MathLib::abs(tok->str());
5756+
const bool unsignedSuffix = (tokStr.find_last_of("uU") != std::string::npos);
57565757
ValueType::Sign sign = unsignedSuffix ? ValueType::Sign::UNSIGNED : ValueType::Sign::SIGNED;
5757-
ValueType::Type type;
5758-
const MathLib::bigint value = MathLib::toLongNumber(tok->str());
5759-
if (mSettings->platformType == cppcheck::Platform::Unspecified)
5760-
type = ValueType::Type::INT;
5761-
else if (mSettings->isIntValue(unsignedSuffix ? (value >> 1) : value))
5762-
type = ValueType::Type::INT;
5763-
else if (mSettings->isLongValue(unsignedSuffix ? (value >> 1) : value))
5764-
type = ValueType::Type::LONG;
5765-
else
5766-
type = ValueType::Type::LONGLONG;
5767-
if (MathLib::isIntHex(tok->str()))
5768-
sign = ValueType::Sign::UNSIGNED;
5769-
for (std::size_t pos = tok->str().size() - 1U; pos > 0U; --pos) {
5770-
const char suffix = tok->str()[pos];
5758+
ValueType::Type type = ValueType::Type::INT;
5759+
const MathLib::biguint value = MathLib::toULongNumber(tokStr);
5760+
for (std::size_t pos = tokStr.size() - 1U; pos > 0U; --pos) {
5761+
const char suffix = tokStr[pos];
57715762
if (suffix == 'u' || suffix == 'U')
57725763
sign = ValueType::Sign::UNSIGNED;
57735764
else if (suffix == 'l' || suffix == 'L')
57745765
type = (type == ValueType::Type::INT) ? ValueType::Type::LONG : ValueType::Type::LONGLONG;
5775-
else if (pos > 2U && suffix == '4' && tok->str()[pos - 1] == '6' && tok->str()[pos - 2] == 'i') {
5766+
else if (pos > 2U && suffix == '4' && tokStr[pos - 1] == '6' && tokStr[pos - 2] == 'i') {
57765767
type = ValueType::Type::LONGLONG;
57775768
pos -= 2;
57785769
} else break;
57795770
}
5771+
if (mSettings->platformType != cppcheck::Platform::Unspecified) {
5772+
if (type <= ValueType::Type::INT && mSettings->isIntValue(unsignedSuffix ? (value >> 1) : value))
5773+
type = ValueType::Type::INT;
5774+
else if (type <= ValueType::Type::INT && !MathLib::isDec(tokStr) && mSettings->isIntValue(value >> 2)) {
5775+
type = ValueType::Type::INT;
5776+
sign = ValueType::Sign::UNSIGNED;
5777+
} else if (type <= ValueType::Type::LONG && mSettings->isLongValue(unsignedSuffix ? (value >> 1) : value))
5778+
type = ValueType::Type::LONG;
5779+
else if (type <= ValueType::Type::LONG && !MathLib::isDec(tokStr) && mSettings->isLongValue(value >> 2)) {
5780+
type = ValueType::Type::LONG;
5781+
sign = ValueType::Sign::UNSIGNED;
5782+
} else if (mSettings->isLongLongValue(unsignedSuffix ? (value >> 1) : value))
5783+
type = ValueType::Type::LONGLONG;
5784+
else {
5785+
type = ValueType::Type::LONGLONG;
5786+
sign = ValueType::Sign::UNSIGNED;
5787+
}
5788+
}
5789+
57805790
setValueType(tok, ValueType(sign, type, 0U));
57815791
}
57825792
} else if (tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) {

lib/tokenlist.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,6 @@ void TokenList::addtoken(std::string str, const nonneg int lineno, const nonneg
132132
}
133133
}
134134

135-
// Replace hexadecimal value with decimal
136-
const bool isHex = MathLib::isIntHex(str) ;
137-
if (isHex || MathLib::isOct(str) || MathLib::isBin(str)) {
138-
// TODO: It would be better if TokenList didn't simplify hexadecimal numbers
139-
std::string suffix;
140-
if (isHex &&
141-
str.size() == (2 + mSettings->int_bit / 4) &&
142-
(str[2] >= '8') && // includes A-F and a-f
143-
MathLib::getSuffix(str).empty()
144-
)
145-
suffix = "U";
146-
str = MathLib::value(str).str() + suffix;
147-
}
148-
149135
if (mTokensFrontBack.back) {
150136
mTokensFrontBack.back->insertToken(str);
151137
} else {
@@ -165,20 +151,6 @@ void TokenList::addtoken(std::string str, const Token *locationTok)
165151
if (str.empty())
166152
return;
167153

168-
// Replace hexadecimal value with decimal
169-
const bool isHex = MathLib::isIntHex(str) ;
170-
if (isHex || MathLib::isOct(str) || MathLib::isBin(str)) {
171-
// TODO: It would be better if TokenList didn't simplify hexadecimal numbers
172-
std::string suffix;
173-
if (isHex &&
174-
str.size() == (2 + mSettings->int_bit / 4) &&
175-
(str[2] >= '8') && // includes A-F and a-f
176-
MathLib::getSuffix(str).empty()
177-
)
178-
suffix = "U";
179-
str = MathLib::value(str).str() + suffix;
180-
}
181-
182154
if (mTokensFrontBack.back) {
183155
mTokensFrontBack.back->insertToken(str);
184156
} else {
@@ -366,22 +338,6 @@ void TokenList::createTokens(const simplecpp::TokenList *tokenList)
366338

367339
std::string str = tok->str();
368340

369-
// Replace hexadecimal value with decimal
370-
// TODO: Remove this
371-
const bool isHex = MathLib::isIntHex(str) ;
372-
if (isHex || MathLib::isOct(str) || MathLib::isBin(str)) {
373-
// TODO: It would be better if TokenList didn't simplify hexadecimal numbers
374-
std::string suffix;
375-
if (isHex &&
376-
mSettings &&
377-
str.size() == (2 + mSettings->int_bit / 4) &&
378-
(str[2] >= '8') && // includes A-F and a-f
379-
MathLib::getSuffix(str).empty()
380-
)
381-
suffix = "U";
382-
str = MathLib::value(str).str() + suffix;
383-
}
384-
385341
// Float literal
386342
if (str.size() > 1 && str[0] == '.' && std::isdigit(str[1]))
387343
str = '0' + str;

test/testcondition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class TestCondition : public TestFixture {
167167
" int y = x | 0x14;\n"
168168
" if (y == 0x710);\n"
169169
"}");
170-
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==1808' is always false.\n", errout.str());
170+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==0x710' is always false.\n", errout.str());
171171

172172
check("void foo(int x) {\n"
173173
" int y = x | 0x14;\n"

test/testmathlib.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,13 +1157,15 @@ class TestMathLib : public TestFixture {
11571157
ASSERT_EQUALS("0.0", MathLib::tan("0"));
11581158
}
11591159
void abs() const {
1160-
ASSERT_EQUALS("0.0", MathLib::abs("0"));
1161-
ASSERT_EQUALS("0.0", MathLib::abs("+0"));
1162-
ASSERT_EQUALS("0.0", MathLib::abs("-0"));
1163-
ASSERT_EQUALS("1.0", MathLib::abs("+1"));
1164-
ASSERT_EQUALS("1.0", MathLib::abs("+1.0"));
1165-
ASSERT_EQUALS("1.0", MathLib::abs("-1"));
1160+
ASSERT_EQUALS("", MathLib::abs(""));
1161+
ASSERT_EQUALS("0", MathLib::abs("0"));
1162+
ASSERT_EQUALS("+0", MathLib::abs("+0"));
1163+
ASSERT_EQUALS("0", MathLib::abs("-0"));
1164+
ASSERT_EQUALS("+1", MathLib::abs("+1"));
1165+
ASSERT_EQUALS("+1.0", MathLib::abs("+1.0"));
1166+
ASSERT_EQUALS("1", MathLib::abs("-1"));
11661167
ASSERT_EQUALS("1.0", MathLib::abs("-1.0"));
1168+
ASSERT_EQUALS("9007199254740991", MathLib::abs("9007199254740991"));
11671169
}
11681170

11691171
void toString() const {

test/testother.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4296,7 +4296,7 @@ class TestOther : public TestFixture {
42964296
" if ((x == 1) && (x == 0x00000001))\n"
42974297
" a++;\n"
42984298
"}");
4299-
ASSERT_EQUALS("[test.cpp:2]: (style) Same expression on both sides of '&&'.\n", errout.str());
4299+
ASSERT_EQUALS("[test.cpp:2]: (style) Same expression on both sides of '&&' because 'x==1' and 'x==0x00000001' represent the same value.\n", errout.str());
43004300

43014301
check("void f() {\n"
43024302
" enum { Four = 4 };\n"
@@ -8300,13 +8300,13 @@ class TestOther : public TestFixture {
83008300
"void f(int x) {\n"
83018301
" g((x & 0x01) >> 7);\n"
83028302
"}\n");
8303-
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(x&1)>>7' to function g is always 0\n", errout.str());
8303+
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(x&0x01)>>7' to function g is always 0\n", errout.str());
83048304

83058305
check("void g(int);\n"
83068306
"void f(int x) {\n"
83078307
" g((int)((x & 0x01) >> 7));\n"
83088308
"}\n");
8309-
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(int)((x&1)>>7)' to function g is always 0\n", errout.str());
8309+
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(int)((x&0x01)>>7)' to function g is always 0\n", errout.str());
83108310

83118311
check("void g(int);\n"
83128312
"void f(int x) {\n"

test/testsimplifytokens.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,7 +3090,7 @@ class TestSimplifyTokens : public TestFixture {
30903090
void cAlternativeTokens() {
30913091
ASSERT_EQUALS("void f ( ) { err |= ( ( r & s ) && ! t ) ; }",
30923092
tok("void f() { err or_eq ((r bitand s) and not t); }", "test.c", false));
3093-
ASSERT_EQUALS("void f ( ) const { r = f ( a [ 4 ] | 15 , ~ c , ! d ) ; }",
3093+
ASSERT_EQUALS("void f ( ) const { r = f ( a [ 4 ] | 0x0F , ~ c , ! d ) ; }",
30943094
tok("void f() const { r = f(a[4] bitor 0x0F, compl c, not d) ; }", "test.c", false));
30953095

30963096
}
@@ -3386,12 +3386,12 @@ class TestSimplifyTokens : public TestFixture {
33863386

33873387
{
33883388
const char code[] = "int vals[] = { 0x13, 1?0x01:0x00 };";
3389-
ASSERT_EQUALS("int vals [ 2 ] = { 19 , 1 } ;", tok(code));
3389+
ASSERT_EQUALS("int vals [ 2 ] = { 0x13 , 0x01 } ;", tok(code));
33903390
}
33913391

33923392
{
33933393
const char code[] = "int vals[] = { 0x13, 0?0x01:0x00 };";
3394-
ASSERT_EQUALS("int vals [ 2 ] = { 19 , 0 } ;", tok(code));
3394+
ASSERT_EQUALS("int vals [ 2 ] = { 0x13 , 0x00 } ;", tok(code));
33953395
}
33963396

33973397
{
@@ -4901,7 +4901,7 @@ class TestSimplifyTokens : public TestFixture {
49014901
" unsigned char override[] = {0x01, 0x02};\n"
49024902
" doSomething(override, sizeof(override));\n"
49034903
"}\n";
4904-
ASSERT_EQUALS("void fun ( ) { char override [ 2 ] = { 1 , 2 } ; doSomething ( override , 2 ) ; }",
4904+
ASSERT_EQUALS("void fun ( ) { char override [ 2 ] = { 0x01 , 0x02 } ; doSomething ( override , 2 ) ; }",
49054905
tok(code, true));
49064906
}
49074907

test/testsymboldatabase.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6496,12 +6496,37 @@ class TestSymbolDatabase: public TestFixture {
64966496
s.long_bit = 32;
64976497
s.long_long_bit = 64;
64986498

6499+
Settings sSameSize;
6500+
sSameSize.int_bit = 32;
6501+
sSameSize.long_bit = 64;
6502+
sSameSize.long_long_bit = 64;
6503+
64996504
// numbers
65006505
ASSERT_EQUALS("signed int", typeOf("1;", "1", "test.c", &s));
6506+
ASSERT_EQUALS("signed int", typeOf("(-1);", "-1", "test.c", &s));
65016507
ASSERT_EQUALS("signed int", typeOf("32767;", "32767", "test.c", &s));
6508+
ASSERT_EQUALS("signed int", typeOf("(-32767);", "-32767", "test.c", &s));
65026509
ASSERT_EQUALS("signed long", typeOf("32768;", "32768", "test.c", &s));
6510+
ASSERT_EQUALS("signed long", typeOf("(-32768);", "-32768", "test.c", &s));
6511+
ASSERT_EQUALS("signed long", typeOf("32768l;", "32768l", "test.c", &s));
65036512
ASSERT_EQUALS("unsigned int", typeOf("32768U;", "32768U", "test.c", &s));
65046513
ASSERT_EQUALS("signed long long", typeOf("2147483648;", "2147483648", "test.c", &s));
6514+
ASSERT_EQUALS("unsigned long", typeOf("2147483648u;", "2147483648u", "test.c", &s));
6515+
ASSERT_EQUALS("signed long long", typeOf("2147483648L;", "2147483648L", "test.c", &s));
6516+
ASSERT_EQUALS("unsigned long long", typeOf("18446744069414584320;", "18446744069414584320", "test.c", &s));
6517+
ASSERT_EQUALS("signed int", typeOf("0xFF;", "0xFF", "test.c", &s));
6518+
ASSERT_EQUALS("unsigned int", typeOf("0xFFU;", "0xFFU", "test.c", &s));
6519+
ASSERT_EQUALS("unsigned int", typeOf("0xFFFF;", "0xFFFF", "test.c", &s));
6520+
ASSERT_EQUALS("signed long", typeOf("0xFFFFFF;", "0xFFFFFF", "test.c", &s));
6521+
ASSERT_EQUALS("unsigned long", typeOf("0xFFFFFFU;", "0xFFFFFFU", "test.c", &s));
6522+
ASSERT_EQUALS("unsigned long", typeOf("0xFFFFFFFF;", "0xFFFFFFFF", "test.c", &s));
6523+
ASSERT_EQUALS("signed long long", typeOf("0xFFFFFFFFFFFF;", "0xFFFFFFFFFFFF", "test.c", &s));
6524+
ASSERT_EQUALS("unsigned long long", typeOf("0xFFFFFFFFFFFFU;", "0xFFFFFFFFFFFFU", "test.c", &s));
6525+
ASSERT_EQUALS("unsigned long long", typeOf("0xFFFFFFFF00000000;", "0xFFFFFFFF00000000", "test.c", &s));
6526+
6527+
ASSERT_EQUALS("signed long", typeOf("2147483648;", "2147483648", "test.c", &sSameSize));
6528+
ASSERT_EQUALS("unsigned long", typeOf("0xc000000000000000;", "0xc000000000000000", "test.c", &sSameSize));
6529+
65056530
ASSERT_EQUALS("unsigned int", typeOf("1U;", "1U"));
65066531
ASSERT_EQUALS("signed long", typeOf("1L;", "1L"));
65076532
ASSERT_EQUALS("unsigned long", typeOf("1UL;", "1UL"));
@@ -6516,11 +6541,26 @@ class TestSymbolDatabase: public TestFixture {
65166541
ASSERT_EQUALS("signed long long", typeOf("1ll;", "1ll"));
65176542
ASSERT_EQUALS("unsigned long long", typeOf("1ull;", "1ull"));
65186543
ASSERT_EQUALS("unsigned long long", typeOf("1llu;", "1llu"));
6544+
ASSERT_EQUALS("signed int", typeOf("01;", "01"));
6545+
ASSERT_EQUALS("unsigned int", typeOf("01U;", "01U"));
6546+
ASSERT_EQUALS("signed long", typeOf("01L;", "01L"));
6547+
ASSERT_EQUALS("unsigned long", typeOf("01UL;", "01UL"));
6548+
ASSERT_EQUALS("signed long long", typeOf("01LL;", "01LL"));
6549+
ASSERT_EQUALS("unsigned long long", typeOf("01ULL;", "01ULL"));
6550+
ASSERT_EQUALS("signed int", typeOf("0B1;", "0B1"));
6551+
ASSERT_EQUALS("signed int", typeOf("0b1;", "0b1"));
6552+
ASSERT_EQUALS("unsigned int", typeOf("0b1U;", "0b1U"));
6553+
ASSERT_EQUALS("signed long", typeOf("0b1L;", "0b1L"));
6554+
ASSERT_EQUALS("unsigned long", typeOf("0b1UL;", "0b1UL"));
6555+
ASSERT_EQUALS("signed long long", typeOf("0b1LL;", "0b1LL"));
6556+
ASSERT_EQUALS("unsigned long long", typeOf("0b1ULL;", "0b1ULL"));
65196557
ASSERT_EQUALS("float", typeOf("1.0F;", "1.0F"));
65206558
ASSERT_EQUALS("float", typeOf("1.0f;", "1.0f"));
65216559
ASSERT_EQUALS("double", typeOf("1.0;", "1.0"));
65226560
ASSERT_EQUALS("double", typeOf("1E3;", "1E3"));
6561+
ASSERT_EQUALS("double", typeOf("0x1.2p3;", "0x1.2p3"));
65236562
ASSERT_EQUALS("long double", typeOf("1.23L;", "1.23L"));
6563+
ASSERT_EQUALS("long double", typeOf("1.23l;", "1.23l"));
65246564

65256565
// Constant calculations
65266566
ASSERT_EQUALS("signed int", typeOf("1 + 2;", "+"));

0 commit comments

Comments
 (0)