From b6276058da692abebcbb3755f1e7257a03d02461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Mar 2014 19:02:33 +0100 Subject: [PATCH] Value Flow: Improved abstract interpretation of arithmetical expressions --- lib/valueflow.cpp | 16 ++++++++++++++++ test/testbufferoverrun.cpp | 3 ++- test/testvalueflow.cpp | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 234b9f6b6..2d5a891bd 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -663,6 +663,22 @@ static void execute(const Token *expr, } } + else if (expr->isArithmeticalOp() && expr->astOperand1() && expr->astOperand2()) { + MathLib::bigint result1, result2; + execute(expr->astOperand1(), programMemory, &result1, error); + execute(expr->astOperand2(), programMemory, &result2, error); + if (expr->str() == "+") + *result = result1 + result2; + else if (expr->str() == "-") + *result = result1 - result2; + else if (expr->str() == "*") + *result = result1 * result2; + else if (expr->str() == "/") + *result = result1 / result2; + else if (expr->str() == "%") + *result = result1 % result2; + } + else if (expr->str() == "&&") { execute(expr->astOperand1(), programMemory, result, error); if (*error || *result == 0) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 4458f144a..67bb1bea7 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -830,7 +830,8 @@ private: " for (int i = 0; i < 4; i+=2)\n" " a[i] = 0;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: a\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: a\n" + "[test.cpp:4]: (error) Array 'a[2]' accessed at index 2, which is out of bounds.\n", errout.str()); check("void f() {\n" // #4398 " int a[2];\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4b2915a01..53c28324f 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -626,6 +626,14 @@ private: ASSERT_EQUALS(true, testValueOfX(code, 3U, 9)); ASSERT_EQUALS(false, testValueOfX(code, 3U, 10)); + code = "void f() {\n" + " for (int x = 0; x < 10; x = x + 2)\n" + " a[x] = 0;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 3U, 8)); + ASSERT_EQUALS(false, testValueOfX(code, 3U, 10)); + code = "void f() {\n" " for (int x = 0; x < 10; x++)\n" " x<4 ?\n"