Fix 10786: False positive: arrayIndexOutOfBoundsCond (#3803)

This commit is contained in:
Paul Fultz II 2022-02-06 13:14:13 -06:00 committed by GitHub
parent a639c59780
commit 569332a50a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 1 deletions

View File

@ -2831,6 +2831,10 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value)
return expr;
MathLib::bigint intval;
const Token* binaryTok = parseBinaryIntOp(expr, intval);
bool rhs = astIsRHS(binaryTok);
// If its on the rhs, then -1 multipllication is needed, which is not possible with simple delta analysis used currentl for symbolic values
if (value.isSymbolicValue() && rhs && Token::simpleMatch(expr, "-"))
return expr;
if (binaryTok && expr->str().size() == 1) {
switch (expr->str()[0]) {
case '+': {
@ -2838,7 +2842,10 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value)
return solveExprValue(binaryTok, value);
}
case '-': {
value.intvalue += intval;
if (rhs)
value.intvalue = intval - value.intvalue;
else
value.intvalue += intval;
return solveExprValue(binaryTok, value);
}
case '*': {

View File

@ -149,6 +149,7 @@ private:
TEST_CASE(valueFlowCrashConstructorInitialization);
TEST_CASE(valueFlowUnknownMixedOperators);
TEST_CASE(valueFlowSolveExpr);
TEST_CASE(valueFlowIdempotent);
TEST_CASE(valueFlowUnsigned);
TEST_CASE(valueFlowMod);
@ -6480,6 +6481,59 @@ private:
ASSERT_EQUALS(false, testValueOfXKnown(code, 4U, 1));
}
void valueFlowSolveExpr()
{
const char* code;
code = "int f(int x) {\n"
" if ((64 - x) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 56));
code = "int f(int x) {\n"
" if ((x - 64) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 72));
code = "int f(int x) {\n"
" if ((x - 64) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 72));
code = "int f(int x) {\n"
" if ((x + 64) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, -56));
code = "int f(int x) {\n"
" if ((x * 2) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 4));
code = "int f(int x) {\n"
" if ((x ^ 64) == 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 72));
code = "int f(int i) {\n"
" int j = i + 64;\n"
" int x = j;\n"
" return x;\n"
"}\n";
TODO_ASSERT_EQUALS(true, false, testValueOfXKnown(code, 4U, "i", 64));
}
void valueFlowIdempotent() {
const char *code;
@ -6860,6 +6914,15 @@ private:
"}\n";
ASSERT_EQUALS(true, testValueOfX(code, 3U, "len", -1));
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, "len", 0));
code = "int f(int x) {\n"
" int i = 64 - x;\n"
" if(i < 8)\n"
" return x;\n"
" return 0;\n"
"}\n";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 71));
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 56));
}
void valueFlowSymbolicIdentity()