Skip to content

Commit b455f84

Browse files
committed
Fixed #10448 (FN compareValueOutOfTypeRangeError with int32_t)
1 parent 8de160a commit b455f84

3 files changed

Lines changed: 42 additions & 14 deletions

File tree

lib/checkcondition.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,26 +1809,49 @@ void CheckCondition::checkCompareValueOutOfTypeRange()
18091809

18101810
const auto typeMinValue = (typeTok->valueType()->sign == ValueType::Sign::UNSIGNED) ? 0 : (-(1LL << (bits-1)));
18111811
const auto unsignedTypeMaxValue = (1LL << bits) - 1LL;
1812-
const auto typeMaxValue = (typeTok->valueType()->sign != ValueType::Sign::SIGNED || bits >= mSettings->int_bit) ?
1813-
unsignedTypeMaxValue : // unsigned type. signed int/long/long long; comparing sign bit is ok. i.e. 'i == 0xffffffff'
1814-
(unsignedTypeMaxValue / 2); // signed char/short
1815-
1816-
if (valueTok->getKnownIntValue() < typeMinValue)
1817-
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue());
1812+
long long typeMaxValue;
1813+
if (typeTok->valueType()->sign != ValueType::Sign::SIGNED)
1814+
typeMaxValue = unsignedTypeMaxValue;
1815+
else if (bits >= mSettings->int_bit && valueTok->valueType()->sign != ValueType::Sign::SIGNED)
1816+
typeMaxValue = unsignedTypeMaxValue;
1817+
else
1818+
typeMaxValue = unsignedTypeMaxValue / 2;
1819+
1820+
bool result;
1821+
if (tok->str() == "==")
1822+
result = false;
1823+
else if (tok->str() == "!=")
1824+
result = true;
1825+
else if (tok->str()[0] == '>' && i == 0)
1826+
// num > var
1827+
result = (valueTok->getKnownIntValue() > 0);
1828+
else if (tok->str()[0] == '>' && i == 1)
1829+
// var > num
1830+
result = (valueTok->getKnownIntValue() < 0);
1831+
else if (tok->str()[0] == '<' && i == 0)
1832+
// num < var
1833+
result = (valueTok->getKnownIntValue() < 0);
1834+
else if (tok->str()[0] == '<' && i == 1)
1835+
// var < num
1836+
result = (valueTok->getKnownIntValue() > 0);
1837+
1838+
if (valueTok->getKnownIntValue() < typeMinValue) {
1839+
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
1840+
}
18181841
else if (valueTok->getKnownIntValue() > typeMaxValue)
1819-
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue());
1842+
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
18201843
}
18211844
}
18221845
}
18231846
}
18241847

1825-
void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value)
1848+
void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value, bool result)
18261849
{
18271850
reportError(
18281851
comparison,
18291852
Severity::style,
18301853
"compareValueOutOfTypeRangeError",
1831-
"Comparing expression of type '" + type + "' against value " + std::to_string(value) + ". Condition is always true/false.",
1854+
"Comparing expression of type '" + type + "' against value " + std::to_string(value) + ". Condition is always " + (result ? "true" : "false") + ".",
18321855
CWE398,
18331856
Certainty::normal);
18341857
}

lib/checkcondition.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class CPPCHECKLIB CheckCondition : public Check {
167167
void assignmentInCondition(const Token *eq);
168168

169169
void checkCompareValueOutOfTypeRange();
170-
void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value);
170+
void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value, bool result);
171171

172172
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
173173
CheckCondition c(nullptr, settings, errorLogger);
@@ -192,7 +192,7 @@ class CPPCHECKLIB CheckCondition : public Check {
192192
c.pointerAdditionResultNotNullError(nullptr, nullptr);
193193
c.duplicateConditionalAssignError(nullptr, nullptr);
194194
c.assignmentInCondition(nullptr);
195-
c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256);
195+
c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256, true);
196196
}
197197

198198
static std::string myName() {

test/testcondition.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4586,7 +4586,7 @@ class TestCondition : public TestFixture {
45864586
check("void f(unsigned char c) {\n"
45874587
" if (c == 256) {}\n"
45884588
"}", &settingsUnix64);
4589-
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always true/false.\n", errout.str());
4589+
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str());
45904590

45914591
check("void f(unsigned char c) {\n"
45924592
" if (c == 255) {}\n"
@@ -4602,12 +4602,12 @@ class TestCondition : public TestFixture {
46024602
check("void f(signed char x) {\n"
46034603
" if (x == 0xff) {}\n"
46044604
"}", &settingsUnix64);
4605-
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always true/false.\n", errout.str());
4605+
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false.\n", errout.str());
46064606

46074607
check("void f(short x) {\n"
46084608
" if (x == 0xffff) {}\n"
46094609
"}", &settingsUnix64);
4610-
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always true/false.\n", errout.str());
4610+
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false.\n", errout.str());
46114611

46124612
check("void f(int x) {\n"
46134613
" if (x == 0xffffffff) {}\n"
@@ -4629,6 +4629,11 @@ class TestCondition : public TestFixture {
46294629
" if ((c = foo()) != -1) {}\n"
46304630
"}", &settingsUnix64);
46314631
ASSERT_EQUALS("", errout.str());
4632+
4633+
check("void f(int x) {\n"
4634+
" if (x < 3000000000) {}\n"
4635+
"}", &settingsUnix64);
4636+
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout.str());
46324637
}
46334638

46344639
void knownConditionCast() { // #9976

0 commit comments

Comments
 (0)