invalidTestForOverflow: Fixed some false negatives (#7184)
This commit is contained in:
parent
fb8cce647c
commit
1b0bb02f1d
|
@ -1030,12 +1030,15 @@ void CheckCondition::checkInvalidTestForOverflow()
|
|||
continue;
|
||||
|
||||
const Token *calcToken, *exprToken;
|
||||
if (tok->str() == "<" && tok->astOperand1()->str() == "+") {
|
||||
bool result;
|
||||
if (Token::Match(tok, "<|>=") && tok->astOperand1()->str() == "+") {
|
||||
calcToken = tok->astOperand1();
|
||||
exprToken = tok->astOperand2();
|
||||
} else if (tok->str() == ">" && tok->astOperand2()->str() == "+") {
|
||||
result = (tok->str() == ">=");
|
||||
} else if (Token::Match(tok, ">|<=") && tok->astOperand2()->str() == "+") {
|
||||
calcToken = tok->astOperand2();
|
||||
exprToken = tok->astOperand1();
|
||||
result = (tok->str() == "<=");
|
||||
} else
|
||||
continue;
|
||||
|
||||
|
@ -1058,18 +1061,20 @@ void CheckCondition::checkInvalidTestForOverflow()
|
|||
|
||||
// Only warn when termToken is always positive
|
||||
if (termToken->valueType() && termToken->valueType()->sign == ValueType::Sign::UNSIGNED)
|
||||
invalidTestForOverflow(tok);
|
||||
invalidTestForOverflow(tok, result);
|
||||
else if (termToken->isNumber() && MathLib::isPositive(termToken->str()))
|
||||
invalidTestForOverflow(tok);
|
||||
invalidTestForOverflow(tok, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckCondition::invalidTestForOverflow(const Token* tok)
|
||||
void CheckCondition::invalidTestForOverflow(const Token* tok, bool result)
|
||||
{
|
||||
std::string errmsg;
|
||||
errmsg = "Invalid test for overflow '" +
|
||||
(tok ? tok->expressionString() : std::string("x + u < x")) +
|
||||
"'. Condition is always false unless there is overflow, and overflow is UB.";
|
||||
"'. Condition is always " +
|
||||
std::string(result ? "true" : "false") +
|
||||
" unless there is overflow, and overflow is UB.";
|
||||
reportError(tok, Severity::warning, "invalidTestForOverflow", errmsg);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ private:
|
|||
|
||||
void alwaysTrueFalseError(const Token *tok, bool knownResult);
|
||||
|
||||
void invalidTestForOverflow(const Token* tok);
|
||||
void invalidTestForOverflow(const Token* tok, bool result);
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
CheckCondition c(0, settings, errorLogger);
|
||||
|
@ -142,7 +142,7 @@ private:
|
|||
c.moduloAlwaysTrueFalseError(0, "1");
|
||||
c.clarifyConditionError(0, true, false);
|
||||
c.alwaysTrueFalseError(0, true);
|
||||
c.invalidTestForOverflow(0);
|
||||
c.invalidTestForOverflow(0, false);
|
||||
}
|
||||
|
||||
static std::string myName() {
|
||||
|
|
|
@ -1613,6 +1613,21 @@ private:
|
|||
"}");
|
||||
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());
|
||||
|
||||
check("void f(char *p, unsigned int x) {\n"
|
||||
" assert((p + x) >= p);\n"
|
||||
"}");
|
||||
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());
|
||||
|
||||
check("void f(char *p, unsigned int x) {\n"
|
||||
" assert(p > (p + x));\n"
|
||||
"}");
|
||||
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());
|
||||
|
||||
check("void f(char *p, unsigned int x) {\n"
|
||||
" assert(p <= (p + x));\n"
|
||||
"}");
|
||||
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());
|
||||
|
||||
check("void f(signed int x) {\n"
|
||||
" assert(x + 100 < x);\n"
|
||||
"}");
|
||||
|
|
Loading…
Reference in New Issue