Fix 10786: False positive: arrayIndexOutOfBoundsCond (#3803)
This commit is contained in:
parent
a639c59780
commit
569332a50a
|
@ -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 '*': {
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue