Fix some false positive in loop forward analysis (#2669)
* Fix some false positive in loop forward analysis In cases like: ``` bool b(); void f() { int val[50]; int i, sum=0; for (i = 1; b() && i < 50; i++) sum += val[i]; for (; i < 50; i++) sum -= val[i]; } ``` The forward analysis assumed the second loop was entered, and we ended up with false positive in it: `Array 'val[50]' accessed at index 50, which is out of bounds` * Fix style
This commit is contained in:
parent
92f95c850e
commit
8c2c81dbcd
|
@ -220,8 +220,17 @@ struct ForwardTraversal {
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
}
|
}
|
||||||
// Traverse condition after lowering
|
// Traverse condition after lowering
|
||||||
if (condTok && updateRecursive(condTok) == Progress::Break)
|
if (condTok) {
|
||||||
|
if (updateRecursive(condTok) == Progress::Break)
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
|
|
||||||
|
bool checkThen, checkElse;
|
||||||
|
std::tie(checkThen, checkElse) = evalCond(condTok);
|
||||||
|
if (checkElse)
|
||||||
|
// condition is false, we don't enter the loop
|
||||||
|
return Progress::Break;
|
||||||
|
}
|
||||||
|
|
||||||
forkScope(endBlock, allAnalysis.isModified());
|
forkScope(endBlock, allAnalysis.isModified());
|
||||||
if (bodyAnalysis.isModified()) {
|
if (bodyAnalysis.isModified()) {
|
||||||
Token* writeTok = findRange(endBlock->link(), endBlock, std::mem_fn(&ForwardAnalyzer::Action::isModified));
|
Token* writeTok = findRange(endBlock->link(), endBlock, std::mem_fn(&ForwardAnalyzer::Action::isModified));
|
||||||
|
|
|
@ -156,6 +156,7 @@ private:
|
||||||
TEST_CASE(array_index_function_parameter);
|
TEST_CASE(array_index_function_parameter);
|
||||||
TEST_CASE(array_index_enum_array); // #8439
|
TEST_CASE(array_index_enum_array); // #8439
|
||||||
TEST_CASE(array_index_container); // #9386
|
TEST_CASE(array_index_container); // #9386
|
||||||
|
TEST_CASE(array_index_two_for_loops);
|
||||||
|
|
||||||
TEST_CASE(buffer_overrun_2_struct);
|
TEST_CASE(buffer_overrun_2_struct);
|
||||||
TEST_CASE(buffer_overrun_3);
|
TEST_CASE(buffer_overrun_3);
|
||||||
|
@ -2211,6 +2212,46 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void array_index_two_for_loops() {
|
||||||
|
check("bool b();\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" int val[50];\n"
|
||||||
|
" int i, sum=0;\n"
|
||||||
|
" for (i = 1; b() && i < 50; i++)\n"
|
||||||
|
" sum += val[i];\n"
|
||||||
|
" if (i < 50)\n"
|
||||||
|
" sum -= val[i];\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("bool b();\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" int val[50];\n"
|
||||||
|
" int i, sum=0;\n"
|
||||||
|
" for (i = 1; b() && i < 50; i++)\n"
|
||||||
|
" sum += val[i];\n"
|
||||||
|
" for (; i < 50;) {\n"
|
||||||
|
" sum -= val[i];\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("bool b();\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" int val[50];\n"
|
||||||
|
" int i, sum=0;\n"
|
||||||
|
" for (i = 1; b() && i < 50; i++)\n"
|
||||||
|
" sum += val[i];\n"
|
||||||
|
" for (; i < 50; i++)\n"
|
||||||
|
" sum -= val[i];\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void buffer_overrun_2_struct() {
|
void buffer_overrun_2_struct() {
|
||||||
check("struct ABC\n"
|
check("struct ABC\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue