Fixed #10448 (FN compareValueOutOfTypeRangeError with int32_t)
This commit is contained in:
parent
8de160a163
commit
b455f847ba
|
@ -1809,26 +1809,49 @@ void CheckCondition::checkCompareValueOutOfTypeRange()
|
|||
|
||||
const auto typeMinValue = (typeTok->valueType()->sign == ValueType::Sign::UNSIGNED) ? 0 : (-(1LL << (bits-1)));
|
||||
const auto unsignedTypeMaxValue = (1LL << bits) - 1LL;
|
||||
const auto typeMaxValue = (typeTok->valueType()->sign != ValueType::Sign::SIGNED || bits >= mSettings->int_bit) ?
|
||||
unsignedTypeMaxValue : // unsigned type. signed int/long/long long; comparing sign bit is ok. i.e. 'i == 0xffffffff'
|
||||
(unsignedTypeMaxValue / 2); // signed char/short
|
||||
long long typeMaxValue;
|
||||
if (typeTok->valueType()->sign != ValueType::Sign::SIGNED)
|
||||
typeMaxValue = unsignedTypeMaxValue;
|
||||
else if (bits >= mSettings->int_bit && valueTok->valueType()->sign != ValueType::Sign::SIGNED)
|
||||
typeMaxValue = unsignedTypeMaxValue;
|
||||
else
|
||||
typeMaxValue = unsignedTypeMaxValue / 2;
|
||||
|
||||
if (valueTok->getKnownIntValue() < typeMinValue)
|
||||
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue());
|
||||
bool result;
|
||||
if (tok->str() == "==")
|
||||
result = false;
|
||||
else if (tok->str() == "!=")
|
||||
result = true;
|
||||
else if (tok->str()[0] == '>' && i == 0)
|
||||
// num > var
|
||||
result = (valueTok->getKnownIntValue() > 0);
|
||||
else if (tok->str()[0] == '>' && i == 1)
|
||||
// var > num
|
||||
result = (valueTok->getKnownIntValue() < 0);
|
||||
else if (tok->str()[0] == '<' && i == 0)
|
||||
// num < var
|
||||
result = (valueTok->getKnownIntValue() < 0);
|
||||
else if (tok->str()[0] == '<' && i == 1)
|
||||
// var < num
|
||||
result = (valueTok->getKnownIntValue() > 0);
|
||||
|
||||
if (valueTok->getKnownIntValue() < typeMinValue) {
|
||||
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
|
||||
}
|
||||
else if (valueTok->getKnownIntValue() > typeMaxValue)
|
||||
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue());
|
||||
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value)
|
||||
void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value, bool result)
|
||||
{
|
||||
reportError(
|
||||
comparison,
|
||||
Severity::style,
|
||||
"compareValueOutOfTypeRangeError",
|
||||
"Comparing expression of type '" + type + "' against value " + std::to_string(value) + ". Condition is always true/false.",
|
||||
"Comparing expression of type '" + type + "' against value " + std::to_string(value) + ". Condition is always " + (result ? "true" : "false") + ".",
|
||||
CWE398,
|
||||
Certainty::normal);
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ private:
|
|||
void assignmentInCondition(const Token *eq);
|
||||
|
||||
void checkCompareValueOutOfTypeRange();
|
||||
void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value);
|
||||
void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, long long value, bool result);
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
|
||||
CheckCondition c(nullptr, settings, errorLogger);
|
||||
|
@ -192,7 +192,7 @@ private:
|
|||
c.pointerAdditionResultNotNullError(nullptr, nullptr);
|
||||
c.duplicateConditionalAssignError(nullptr, nullptr);
|
||||
c.assignmentInCondition(nullptr);
|
||||
c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256);
|
||||
c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256, true);
|
||||
}
|
||||
|
||||
static std::string myName() {
|
||||
|
|
|
@ -4586,7 +4586,7 @@ private:
|
|||
check("void f(unsigned char c) {\n"
|
||||
" if (c == 256) {}\n"
|
||||
"}", &settingsUnix64);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always true/false.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str());
|
||||
|
||||
check("void f(unsigned char c) {\n"
|
||||
" if (c == 255) {}\n"
|
||||
|
@ -4602,12 +4602,12 @@ private:
|
|||
check("void f(signed char x) {\n"
|
||||
" if (x == 0xff) {}\n"
|
||||
"}", &settingsUnix64);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always true/false.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false.\n", errout.str());
|
||||
|
||||
check("void f(short x) {\n"
|
||||
" if (x == 0xffff) {}\n"
|
||||
"}", &settingsUnix64);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always true/false.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false.\n", errout.str());
|
||||
|
||||
check("void f(int x) {\n"
|
||||
" if (x == 0xffffffff) {}\n"
|
||||
|
@ -4629,6 +4629,11 @@ private:
|
|||
" if ((c = foo()) != -1) {}\n"
|
||||
"}", &settingsUnix64);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(int x) {\n"
|
||||
" if (x < 3000000000) {}\n"
|
||||
"}", &settingsUnix64);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout.str());
|
||||
}
|
||||
|
||||
void knownConditionCast() { // #9976
|
||||
|
|
Loading…
Reference in New Issue