Fix #8545 FN Condition '...' is always true ' uint16_t i; ( i <= 0xFFFF)' (#4114)

This commit is contained in:
chrchr-github 2022-05-21 08:33:42 +02:00 committed by GitHub
parent feaef46436
commit 2a7f00cf9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 12 deletions

View File

@ -1830,29 +1830,58 @@ void CheckCondition::checkCompareValueOutOfTypeRange()
else
typeMaxValue = unsignedTypeMaxValue / 2;
bool result;
bool result{};
const auto kiv = valueTok->getKnownIntValue();
if (tok->str() == "==")
result = false;
else if (tok->str() == "!=")
result = true;
else if (tok->str()[0] == '>' && i == 0)
// num > var
result = (valueTok->getKnownIntValue() > 0);
result = (kiv > 0);
else if (tok->str()[0] == '>' && i == 1)
// var > num
result = (valueTok->getKnownIntValue() < 0);
result = (kiv < 0);
else if (tok->str()[0] == '<' && i == 0)
// num < var
result = (valueTok->getKnownIntValue() < 0);
result = (kiv < 0);
else if (tok->str()[0] == '<' && i == 1)
// var < num
result = (valueTok->getKnownIntValue() > 0);
result = (kiv > 0);
if (valueTok->getKnownIntValue() < typeMinValue) {
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
bool error = false;
if (kiv < typeMinValue || kiv > typeMaxValue) {
error = true;
} else {
switch (i) {
case 0: // num cmp var
if (kiv == typeMinValue) {
if (tok->str() == "<=") {
result = true;
error = true;
} else if (tok->str() == ">")
error = true;
}
else if (kiv == typeMaxValue && (tok->str() == ">=" || tok->str() == "<")) {
error = true;
}
break;
case 1: // var cmp num
if (kiv == typeMinValue) {
if (tok->str() == ">=") {
result = true;
error = true;
} else if (tok->str() == "<")
error = true;
}
else if (kiv == typeMaxValue && (tok->str() == "<=" || tok->str() == ">")) {
error = true;
}
break;
}
}
else if (valueTok->getKnownIntValue() > typeMaxValue)
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result);
if (error)
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), kiv, result);
}
}
}

View File

@ -71,8 +71,8 @@ TEST(Test, warning_in_assert_macros)
ASSERT_GE(i, i);
unsigned int u = errno;
// cppcheck-suppress unsignedPositive
// cppcheck-suppress [unsignedPositive, compareValueOutOfTypeRangeError]
ASSERT_GE(u, 0);
// cppcheck-suppress unsignedLessThanZero
// cppcheck-suppress [unsignedLessThanZero, compareValueOutOfTypeRangeError]
ASSERT_LT(u, 0);
}

View File

@ -23,7 +23,7 @@ CPPCHECK="$DIR"../../cppcheck
CFG="$DIR"../../cfg/
# Cppcheck options
CPPCHECK_OPT='--check-library --enable=information --enable=style --error-exitcode=-1 --suppress=missingIncludeSystem --inline-suppr --template="{file}:{line}:{severity}:{id}:{message}"'
CPPCHECK_OPT='--check-library --platform=unix64 --enable=information --enable=style --error-exitcode=-1 --suppress=missingIncludeSystem --inline-suppr --template="{file}:{line}:{severity}:{id}:{message}"'
# Compiler settings
CXX=g++

View File

@ -5181,6 +5181,48 @@ private:
" 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());
check("void f(const signed char i) {\n" // #8545
" if (i > -129) {}\n" // warn
" if (i >= -128) {}\n" // warn
" if (i >= -127) {}\n"
" if (i < +128) {}\n" // warn
" if (i <= +127) {}\n" // warn
" if (i <= +126) {}\n"
"}\n", &settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'const signed char' against value -129. Condition is always true.\n"
"[test.cpp:3]: (style) Comparing expression of type 'const signed char' against value -128. Condition is always true.\n"
"[test.cpp:5]: (style) Comparing expression of type 'const signed char' against value 128. Condition is always true.\n"
"[test.cpp:6]: (style) Comparing expression of type 'const signed char' against value 127. Condition is always true.\n",
errout.str());
check("void f(const unsigned char u) {\n"
" if (u > 0) {}\n"
" if (u < 0) {}\n" // warn
" if (u >= 0) {}\n" // warn
" if (u <= 0) {}\n"
" if (u > 255) {}\n" // warn
" if (u < 255) {}\n"
" if (u >= 255) {}\n"
" if (u <= 255) {}\n" // warn
" if (0 < u) {}\n"
" if (0 > u) {}\n" // warn
" if (0 <= u) {}\n" // warn
" if (0 >= u) {}\n"
" if (255 < u) {}\n" // warn
" if (255 > u) {}\n"
" if (255 <= u) {}\n"
" if (255 >= u) {}\n" // warn
"}\n", &settingsUnix64);
ASSERT_EQUALS("[test.cpp:3]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n"
"[test.cpp:4]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n"
"[test.cpp:6]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n"
"[test.cpp:9]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always true.\n"
"[test.cpp:11]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n"
"[test.cpp:12]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n"
"[test.cpp:14]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n"
"[test.cpp:17]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always true.\n",
errout.str());
}
void knownConditionCast() { // #9976