diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 237a10ce7..954f03af0 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -273,13 +273,27 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con Token::Match(tok3, "%varid% = %num% + %varid% )", counter_varid)) { const int num = std::atoi(tok3->strAt(2)); - if (num > value) + + // We have for example code: "for(i=2;i<22;i+=6) + // We can calculate that max value for i is 20, not 21 + // 21-2 = 19 + // 19/6 = 3 + // 6*3+2 = 20 + long max = MathLib::toLongNumber(max_counter_value); + long min = MathLib::toLongNumber(min_counter_value); + max = ((max - min) / num) * num + min; + max_counter_value = MathLib::toString(max); + if (max <= size) condition_out_of_bounds = false; } else if (Token::Match(tok3, "%varid% = %varid% + %num% )", counter_varid)) { const int num = std::atoi(tok3->strAt(4)); - if (num > value) + long max = MathLib::toLongNumber(max_counter_value); + long min = MathLib::toLongNumber(min_counter_value); + max = ((max - min) / num) * num + min; + max_counter_value = MathLib::toString(max); + if (max <= size) condition_out_of_bounds = false; } else if (! Token::Match(tok3, "++| %varid% ++| )", counter_varid)) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 6f386366e..ee57419b4 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -495,6 +495,22 @@ private: " a[i*2] = i;\n" "}\n"); ASSERT_EQUALS("[test.cpp:5]: (possible error) Array index out of bounds\n", errout.str()); + + check("void f()\n" + "{\n" + " int a[12];\n" + " for (int i = 0; i < 12; i+=6)\n" + " a[i+5] = i;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " int a[12];\n" + " for (int i = 0; i < 12; i+=6)\n" + " a[i+6] = i;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (possible error) Array index out of bounds\n", errout.str()); } void buffer_overrun_1()