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;
|
*error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (expr->str() == "++") {
|
else if (expr->str() == "++" || expr->str() == "--") {
|
||||||
if (!expr->astOperand1() || expr->astOperand1()->varId() == 0U)
|
if (!expr->astOperand1() || expr->astOperand1()->varId() == 0U)
|
||||||
*error = true;
|
*error = true;
|
||||||
else {
|
else {
|
||||||
|
@ -663,7 +663,7 @@ static void execute(const Token *expr,
|
||||||
if (var == programMemory->end())
|
if (var == programMemory->end())
|
||||||
*error = true;
|
*error = true;
|
||||||
else {
|
else {
|
||||||
*result = var->second + 1;
|
*result = var->second + (expr->str() == "++" ? 1 : -1);
|
||||||
var->second = *result;
|
var->second = *result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -757,8 +757,7 @@ static bool valueFlowForLoop2(const Token *tok,
|
||||||
if (error)
|
if (error)
|
||||||
return false;
|
return false;
|
||||||
execute(secondExpression, &programMemory, &result, &error);
|
execute(secondExpression, &programMemory, &result, &error);
|
||||||
if (error)
|
|
||||||
return false;
|
|
||||||
std::map<unsigned int, MathLib::bigint> startMemory(programMemory);
|
std::map<unsigned int, MathLib::bigint> startMemory(programMemory);
|
||||||
std::map<unsigned int, MathLib::bigint> endMemory;
|
std::map<unsigned int, MathLib::bigint> endMemory;
|
||||||
|
|
||||||
|
@ -771,9 +770,10 @@ static bool valueFlowForLoop2(const Token *tok,
|
||||||
}
|
}
|
||||||
|
|
||||||
memory1->swap(startMemory);
|
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)
|
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"
|
" for (int i = 3; 0 <= i; i--)\n"
|
||||||
" a[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"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1536,7 +1537,8 @@ private:
|
||||||
" buffer[i] = i;\n"
|
" buffer[i] = i;\n"
|
||||||
" }\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
|
// Correct access limits -> i from 9 to 0
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
|
@ -1768,7 +1770,8 @@ private:
|
||||||
" data[i] = 0;\n"
|
" data[i] = 0;\n"
|
||||||
" }\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"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1902,7 +1905,8 @@ private:
|
||||||
" a[i] = 0;\n"
|
" a[i] = 0;\n"
|
||||||
" }\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() {
|
void array_index_for_neq() {
|
||||||
|
|
|
@ -645,7 +645,7 @@ private:
|
||||||
" for (int x = 0; x < 10; x = x / 0)\n"
|
" for (int x = 0; x < 10; x = x / 0)\n"
|
||||||
" a[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"
|
code = "void f() {\n"
|
||||||
" for (int x = 0; x < 10; x++)\n"
|
" for (int x = 0; x < 10; x++)\n"
|
||||||
|
|
Loading…
Reference in New Issue