ValueFlow: improved abstract interpretation of for loops
This commit is contained in:
parent
c14a3d67bb
commit
dbc8273cb7
|
@ -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<unsigned int, MathLib::bigint> startMemory(programMemory);
|
||||
std::map<unsigned int, MathLib::bigint> endMemory;
|
||||
|
||||
|
@ -771,9 +770,10 @@ static bool valueFlowForLoop2(const Token *tok,
|
|||
}
|
||||
|
||||
memory1->swap(startMemory);
|
||||
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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue