Fix 10023: ValueFlow; Wrong result of post-increment in reverse analysis (#3289)

This commit is contained in:
Paul Fultz II 2021-06-04 10:20:21 -05:00 committed by GitHub
parent e3b7ceec7e
commit b23c5aa742
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 5 deletions

View File

@ -42,6 +42,11 @@ struct ReverseTraversal {
bool updateRecursive(Token* start) { bool updateRecursive(Token* start) {
bool continueB = true; bool continueB = true;
visitAstNodes(start, [&](Token* tok) { visitAstNodes(start, [&](Token* tok) {
const Token* parent = tok->astParent();
while (Token::simpleMatch(parent, ":"))
parent = parent->astParent();
if (isUnevaluated(tok) || isDeadCode(tok, parent))
return ChildrenToVisit::none;
continueB &= update(tok); continueB &= update(tok);
if (continueB) if (continueB)
return ChildrenToVisit::op1_and_op2; return ChildrenToVisit::op1_and_op2;
@ -73,9 +78,11 @@ struct ReverseTraversal {
return result; return result;
} }
Token* isDeadCode(Token* tok) { Token* isDeadCode(Token* tok, const Token* end = nullptr) {
int opSide = 0; int opSide = 0;
for (; tok && tok->astParent(); tok = tok->astParent()) { for (; tok && tok->astParent(); tok = tok->astParent()) {
if (tok == end)
break;
Token* parent = tok->astParent(); Token* parent = tok->astParent();
if (Token::simpleMatch(parent, ":")) { if (Token::simpleMatch(parent, ":")) {
if (astIsLHS(tok)) if (astIsLHS(tok))
@ -178,8 +185,7 @@ struct ReverseTraversal {
} }
if (!continueB) if (!continueB)
break; break;
Analyzer::Action a = valueFlowGenericForward(assignTop->astOperand2(), analyzer, settings); if (!updateRecursive(assignTop->astOperand2()))
if (a.isModified())
break; break;
tok = previousBeforeAstLeftmostLeaf(assignTop)->next(); tok = previousBeforeAstLeftmostLeaf(assignTop)->next();
continue; continue;

View File

@ -133,6 +133,7 @@ private:
TEST_CASE(array_index_53); // #4750 TEST_CASE(array_index_53); // #4750
TEST_CASE(array_index_54); // #10268 TEST_CASE(array_index_54); // #10268
TEST_CASE(array_index_55); // #10254 TEST_CASE(array_index_55); // #10254
TEST_CASE(array_index_57); // #10023
TEST_CASE(array_index_multidim); TEST_CASE(array_index_multidim);
TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_switch_in_for);
TEST_CASE(array_index_for_in_for); // FP: #2634 TEST_CASE(array_index_for_in_for); // FP: #2634
@ -1593,6 +1594,34 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void array_index_57() {
check("void f(std::vector<int>& v) {\n"
" int a[3] = { 1, 2, 3 };\n"
" int i = 0;\n"
" for (auto& x : v) {\n"
" int c = a[i++];\n"
" if (i == 3)\n"
" i = 0;\n"
" x = c;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f(std::vector<int>& v) {\n"
" int a[3] = { 1, 2, 3 };\n"
" int i = 0;\n"
" for (auto& x : v) {\n"
" int c = a[i++];\n"
" if (i == 4)\n"
" i = 0;\n"
" x = c;\n"
" }\n"
"}\n");
ASSERT_EQUALS(
"[test.cpp:6] -> [test.cpp:5]: (warning) Either the condition 'i==4' is redundant or the array 'a[3]' is accessed at index 3, which is out of bounds.\n",
errout.str());
}
void array_index_multidim() { void array_index_multidim() {
check("void f()\n" check("void f()\n"
"{\n" "{\n"

View File

@ -728,9 +728,8 @@ private:
" if (!p)\n" " if (!p)\n"
" ;\n" " ;\n"
"}"); "}");
TODO_ASSERT_EQUALS( ASSERT_EQUALS(
"[test.cpp:4] -> [test.cpp:3]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p.\n", "[test.cpp:4] -> [test.cpp:3]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p.\n",
"",
errout.str()); errout.str());
// while // while