From dbc8273cb753cb190e2c1cc28d140cb254f26bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 24 Mar 2014 00:16:02 +0100 Subject: [PATCH] ValueFlow: improved abstract interpretation of for loops --- lib/valueflow.cpp | 12 ++++++------ test/testbufferoverrun.cpp | 12 ++++++++---- test/testvalueflow.cpp | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 16a4a8e8d..ca6b1a2d5 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -655,7 +655,7 @@ static void execute(const Token *expr, *error = true; } - else if (expr->str() == "++") { + else if (expr->str() == "++" || expr->str() == "--") { if (!expr->astOperand1() || expr->astOperand1()->varId() == 0U) *error = true; else { @@ -663,7 +663,7 @@ static void execute(const Token *expr, if (var == programMemory->end()) *error = true; else { - *result = var->second + 1; + *result = var->second + (expr->str() == "++" ? 1 : -1); var->second = *result; } } @@ -757,8 +757,7 @@ static bool valueFlowForLoop2(const Token *tok, if (error) return false; execute(secondExpression, &programMemory, &result, &error); - if (error) - return false; + std::map startMemory(programMemory); std::map endMemory; @@ -771,9 +770,10 @@ static bool valueFlowForLoop2(const Token *tok, } memory1->swap(startMemory); - memory2->swap(endMemory); + if (!error) + memory2->swap(endMemory); - return !error; + return true; } static void valueFlowForLoopSimplify(Token * const bodyStart, const unsigned int varid, const MathLib::bigint value, TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 67bb1bea7..b0635a136 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1047,7 +1047,8 @@ private: " for (int i = 3; 0 <= i; i--)\n" " a[i] = i;\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: a\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: a\n" + "[test.cpp:5]: (error) Array 'a[3]' accessed at index 3, which is out of bounds.\n", errout.str()); check("void f()\n" "{\n" @@ -1536,7 +1537,8 @@ private: " buffer[i] = i;\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: buffer\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: buffer\n" + "[test.cpp:5]: (error) Array 'buffer[9]' accessed at index 9, which is out of bounds.\n", errout.str()); // Correct access limits -> i from 9 to 0 check("void f() {\n" @@ -1768,7 +1770,8 @@ private: " data[i] = 0;\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: data\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: data\n" + "[test.cpp:5]: (error) Array 'data[8]' accessed at index 10, which is out of bounds.\n", errout.str()); check("void f()\n" "{\n" @@ -1902,7 +1905,8 @@ private: " a[i] = 0;\n" " }\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[10]' accessed at index 10, which is out of bounds.\n", errout.str()); } void array_index_for_neq() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 2329398a7..a2e965c99 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -645,7 +645,7 @@ private: " for (int x = 0; x < 10; x = x / 0)\n" " a[x] = 0;\n" "}"; - testValueOfX(code, 3U, 0); // don't crash + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); // don't crash code = "void f() {\n" " for (int x = 0; x < 10; x++)\n"