Skip to content

Commit 1b0bb02

Browse files
committed
invalidTestForOverflow: Fixed some false negatives (cppcheck-opensource#7184)
1 parent fb8cce6 commit 1b0bb02

3 files changed

Lines changed: 28 additions & 8 deletions

File tree

lib/checkcondition.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,12 +1030,15 @@ void CheckCondition::checkInvalidTestForOverflow()
10301030
continue;
10311031

10321032
const Token *calcToken, *exprToken;
1033-
if (tok->str() == "<" && tok->astOperand1()->str() == "+") {
1033+
bool result;
1034+
if (Token::Match(tok, "<|>=") && tok->astOperand1()->str() == "+") {
10341035
calcToken = tok->astOperand1();
10351036
exprToken = tok->astOperand2();
1036-
} else if (tok->str() == ">" && tok->astOperand2()->str() == "+") {
1037+
result = (tok->str() == ">=");
1038+
} else if (Token::Match(tok, ">|<=") && tok->astOperand2()->str() == "+") {
10371039
calcToken = tok->astOperand2();
10381040
exprToken = tok->astOperand1();
1041+
result = (tok->str() == "<=");
10391042
} else
10401043
continue;
10411044

@@ -1058,18 +1061,20 @@ void CheckCondition::checkInvalidTestForOverflow()
10581061

10591062
// Only warn when termToken is always positive
10601063
if (termToken->valueType() && termToken->valueType()->sign == ValueType::Sign::UNSIGNED)
1061-
invalidTestForOverflow(tok);
1064+
invalidTestForOverflow(tok, result);
10621065
else if (termToken->isNumber() && MathLib::isPositive(termToken->str()))
1063-
invalidTestForOverflow(tok);
1066+
invalidTestForOverflow(tok, result);
10641067
}
10651068
}
10661069
}
10671070

1068-
void CheckCondition::invalidTestForOverflow(const Token* tok)
1071+
void CheckCondition::invalidTestForOverflow(const Token* tok, bool result)
10691072
{
10701073
std::string errmsg;
10711074
errmsg = "Invalid test for overflow '" +
10721075
(tok ? tok->expressionString() : std::string("x + u < x")) +
1073-
"'. Condition is always false unless there is overflow, and overflow is UB.";
1076+
"'. Condition is always " +
1077+
std::string(result ? "true" : "false") +
1078+
" unless there is overflow, and overflow is UB.";
10741079
reportError(tok, Severity::warning, "invalidTestForOverflow", errmsg);
10751080
}

lib/checkcondition.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class CPPCHECKLIB CheckCondition : public Check {
126126

127127
void alwaysTrueFalseError(const Token *tok, bool knownResult);
128128

129-
void invalidTestForOverflow(const Token* tok);
129+
void invalidTestForOverflow(const Token* tok, bool result);
130130

131131
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
132132
CheckCondition c(0, settings, errorLogger);
@@ -142,7 +142,7 @@ class CPPCHECKLIB CheckCondition : public Check {
142142
c.moduloAlwaysTrueFalseError(0, "1");
143143
c.clarifyConditionError(0, true, false);
144144
c.alwaysTrueFalseError(0, true);
145-
c.invalidTestForOverflow(0);
145+
c.invalidTestForOverflow(0, false);
146146
}
147147

148148
static std::string myName() {

test/testcondition.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,21 @@ class TestCondition : public TestFixture {
16131613
"}");
16141614
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)<p'. Condition is always false unless there is overflow, and overflow is UB.\n", errout.str());
16151615

1616+
check("void f(char *p, unsigned int x) {\n"
1617+
" assert((p + x) >= p);\n"
1618+
"}");
1619+
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)>=p'. Condition is always true unless there is overflow, and overflow is UB.\n", errout.str());
1620+
1621+
check("void f(char *p, unsigned int x) {\n"
1622+
" assert(p > (p + x));\n"
1623+
"}");
1624+
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p>(p+x)'. Condition is always false unless there is overflow, and overflow is UB.\n", errout.str());
1625+
1626+
check("void f(char *p, unsigned int x) {\n"
1627+
" assert(p <= (p + x));\n"
1628+
"}");
1629+
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p<=(p+x)'. Condition is always true unless there is overflow, and overflow is UB.\n", errout.str());
1630+
16161631
check("void f(signed int x) {\n"
16171632
" assert(x + 100 < x);\n"
16181633
"}");

0 commit comments

Comments
 (0)