From 569332a50abe4a20468136dd90427b5267751a61 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 6 Feb 2022 13:14:13 -0600 Subject: [PATCH] Fix 10786: False positive: arrayIndexOutOfBoundsCond (#3803) --- lib/valueflow.cpp | 9 +++++- test/testvalueflow.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index de1dfc2c9..7c2d2ef10 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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 '*': { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 02e885c05..38a27ad7e 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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()