diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 592e34afd..69765dc6b 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -42,6 +42,11 @@ struct ReverseTraversal { bool updateRecursive(Token* start) { bool continueB = true; 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); if (continueB) return ChildrenToVisit::op1_and_op2; @@ -73,9 +78,11 @@ struct ReverseTraversal { return result; } - Token* isDeadCode(Token* tok) { + Token* isDeadCode(Token* tok, const Token* end = nullptr) { int opSide = 0; for (; tok && tok->astParent(); tok = tok->astParent()) { + if (tok == end) + break; Token* parent = tok->astParent(); if (Token::simpleMatch(parent, ":")) { if (astIsLHS(tok)) @@ -178,8 +185,7 @@ struct ReverseTraversal { } if (!continueB) break; - Analyzer::Action a = valueFlowGenericForward(assignTop->astOperand2(), analyzer, settings); - if (a.isModified()) + if (!updateRecursive(assignTop->astOperand2())) break; tok = previousBeforeAstLeftmostLeaf(assignTop)->next(); continue; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index a5fbad263..a574f4718 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -133,6 +133,7 @@ private: TEST_CASE(array_index_53); // #4750 TEST_CASE(array_index_54); // #10268 TEST_CASE(array_index_55); // #10254 + TEST_CASE(array_index_57); // #10023 TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_for_in_for); // FP: #2634 @@ -1593,6 +1594,34 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_57() { + check("void f(std::vector& 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& 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() { check("void f()\n" "{\n" diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 38182b9ba..a14a3b096 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -728,9 +728,8 @@ private: " if (!p)\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", - "", errout.str()); // while