diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 43118fc42..5e694ac5b 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2472,6 +2472,37 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, return false; const Token *ftok = tok->tokAt(2); + if (astIsContainer(tok) && tok->valueType() && tok->valueType()->container) { + const Library::Container* c = tok->valueType()->container; + const Library::Container::Action action = c->getAction(ftok->str()); + if (contains({Library::Container::Action::INSERT, + Library::Container::Action::ERASE, + Library::Container::Action::CHANGE, + Library::Container::Action::CHANGE_CONTENT, + Library::Container::Action::CHANGE_INTERNAL, + Library::Container::Action::CLEAR, + Library::Container::Action::PUSH, + Library::Container::Action::POP, + Library::Container::Action::RESIZE}, + action)) + return true; + const Library::Container::Yield yield = c->getYield(ftok->str()); + // If accessing element check if the element is changed + if (contains({Library::Container::Yield::ITEM, Library::Container::Yield::AT_INDEX}, yield)) { + return isVariableChanged(ftok->next(), indirect, settings, cpp, depth - 1); + } else if (contains({Library::Container::Yield::BUFFER, + Library::Container::Yield::BUFFER_NT, + Library::Container::Yield::START_ITERATOR, + Library::Container::Yield::ITERATOR}, + yield)) { + return isVariableChanged(ftok->next(), indirect + 1, settings, cpp, depth - 1); + } else if (contains({Library::Container::Yield::SIZE, + Library::Container::Yield::EMPTY, + Library::Container::Yield::END_ITERATOR}, + yield)) { + return false; + } + } if (settings) return !settings->library.isFunctionConst(ftok); diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 81994ef7f..2a5640abf 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4910,6 +4910,15 @@ private: " return *it;\n" "}\n"); ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'it!=vector.end()' is always true\n", errout.str()); + + // #11303 + check("void f(int n) {\n" + " std::vector buffer(n);\n" + " if(buffer.back() == 0 ||\n" + " buffer.back() == '\\n' ||\n" + " buffer.back() == '\\0') {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout.str()); } void alwaysTrueLoop()