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 else
typeMaxValue = unsignedTypeMaxValue / 2; typeMaxValue = unsignedTypeMaxValue / 2;
bool result; bool result{};
const auto kiv = valueTok->getKnownIntValue();
if (tok->str() == "==") if (tok->str() == "==")
result = false; result = false;
else if (tok->str() == "!=") else if (tok->str() == "!=")
result = true; result = true;
else if (tok->str()[0] == '>' && i == 0) else if (tok->str()[0] == '>' && i == 0)
// num > var // num > var
result = (valueTok->getKnownIntValue() > 0); result = (kiv > 0);
else if (tok->str()[0] == '>' && i == 1) else if (tok->str()[0] == '>' && i == 1)
// var > num // var > num
result = (valueTok->getKnownIntValue() < 0); result = (kiv < 0);
else if (tok->str()[0] == '<' && i == 0) else if (tok->str()[0] == '<' && i == 0)
// num < var // num < var
result = (valueTok->getKnownIntValue() < 0); result = (kiv < 0);
else if (tok->str()[0] == '<' && i == 1) else if (tok->str()[0] == '<' && i == 1)
// var < num // var < num
result = (valueTok->getKnownIntValue() > 0); result = (kiv > 0);
if (valueTok->getKnownIntValue() < typeMinValue) { bool error = false;
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result); 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 (valueTok->getKnownIntValue() > typeMaxValue) else if (kiv == typeMaxValue && (tok->str() == ">=" || tok->str() == "<")) {
compareValueOutOfTypeRangeError(valueTok, typeTok->valueType()->str(), valueTok->getKnownIntValue(), result); 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;
}
}
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); ASSERT_GE(i, i);
unsigned int u = errno; unsigned int u = errno;
// cppcheck-suppress unsignedPositive // cppcheck-suppress [unsignedPositive, compareValueOutOfTypeRangeError]
ASSERT_GE(u, 0); ASSERT_GE(u, 0);
// cppcheck-suppress unsignedLessThanZero // cppcheck-suppress [unsignedLessThanZero, compareValueOutOfTypeRangeError]
ASSERT_LT(u, 0); ASSERT_LT(u, 0);
} }

View File

@ -23,7 +23,7 @@ CPPCHECK="$DIR"../../cppcheck
CFG="$DIR"../../cfg/ CFG="$DIR"../../cfg/
# Cppcheck options # 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 # Compiler settings
CXX=g++ CXX=g++

View File

@ -5181,6 +5181,48 @@ private:
" if (x < 3000000000) {}\n" " if (x < 3000000000) {}\n"
"}", &settingsUnix64); "}", &settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout.str()); 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 void knownConditionCast() { // #9976