From bcbc29affb871daf968d4b538fa3873981f70ac4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 Apr 2022 14:08:44 +0200 Subject: [PATCH] Fix #10526 FP: negativeIndex if function call is made after index check (#4052) * Fix #10526 FP: negativeIndex if function call is made after index check * Improve container check * Format --- lib/valueflow.cpp | 9 ++++++--- test/testbufferoverrun.cpp | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4bb98c250..5a72f3737 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2253,10 +2253,13 @@ struct ValueFlowAnalyzer : Analyzer { } else if (getSettings()->library.getFunction(tok)) { // Assume library function doesn't modify user-global variables return Action::None; - // Function cast does not modify global variables - } else if (tok->tokType() == Token::eType && astIsPrimitive(tok->next())) { + } else if (Token::simpleMatch(tok->astParent(), ".") && astIsContainer(tok->astParent()->astOperand1())) { + // Assume container member function doesn't modify user-global variables return Action::None; - } else if (Token::Match(tok, "%name% (")) { + } else if (tok->tokType() == Token::eType && astIsPrimitive(tok->next())) { + // Function cast does not modify global variables + return Action::None; + } else if (!tok->isKeyword() && Token::Match(tok, "%name% (")) { return Action::Invalid; } return Action::None; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 0f455c52f..7439d5f0e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -197,6 +197,7 @@ private: TEST_CASE(array_index_negative2); // ticket #3063 TEST_CASE(array_index_negative3); TEST_CASE(array_index_negative4); + TEST_CASE(array_index_negative5); // #10526 TEST_CASE(array_index_for_decr); TEST_CASE(array_index_varnames); // FP: struct member #1576, FN: #1586 TEST_CASE(array_index_for_continue); // for,continue @@ -2093,6 +2094,24 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_negative5() // #10526 + { + check("int i;\n" + "std::vector v;\n" + "bool f() {\n" + " if (i != 0) {\n" + " if (v.begin() != v.end()) {\n" + " if (i < 0)\n" + " return false;\n" + " const int a[4] = { 0, 1, 2, 3 };\n" + " return a[i - 1] > 0;\n" + " }\n" + " }\n" + " return false;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void array_index_for_decr() { check("void f()\n" "{\n"