diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 1b18e0150..f8130d9e7 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1435,23 +1435,22 @@ void CheckStl::readingEmptyStlContainer_parseUsage(const Token* tok, const Libra } else if (!noerror) readingEmptyStlContainerError(tok); } else if (Token::Match(tok, "%name% . %type% (")) { - const Library::Container::Yield yield = container->getYield(tok->strAt(2)); - const Token* parent = tok->tokAt(3)->astParent(); // Member function call - if (yield != Library::Container::NO_YIELD && - ((yield != Library::Container::ITERATOR && - yield != Library::Container::START_ITERATOR && - yield != Library::Container::END_ITERATOR) || !parent || Token::Match(parent, "%cop%|=|*"))) { // These functions read from the container - if (!noerror) - readingEmptyStlContainerError(tok); - } else { - const Library::Container::Action action = container->getAction(tok->strAt(2)); - if (action == Library::Container::FIND || action == Library::Container::ERASE || action == Library::Container::POP || action == Library::Container::CLEAR) { - if (!noerror) - readingEmptyStlContainerError(tok); - } else - empty.erase(tok->varId()); + const Library::Container::Action action = container->getAction(tok->strAt(2)); + if ((action == Library::Container::FIND || action == Library::Container::ERASE || action == Library::Container::POP || action == Library::Container::CLEAR) && !noerror) { + readingEmptyStlContainerError(tok); + return; } + + const Token* parent = tok->tokAt(3)->astParent(); + const Library::Container::Yield yield = container->getYield(tok->strAt(2)); + bool yieldsIterator = (yield == Library::Container::ITERATOR || yield == Library::Container::START_ITERATOR || yield == Library::Container::END_ITERATOR); + if (yield != Library::Container::NO_YIELD && + (!parent || Token::Match(parent, "%cop%|*") || parent->isAssignmentOp() || !yieldsIterator)) { // These functions read from the container + if (!noerror && (!yieldsIterator || !parent || !parent->isAssignmentOp())) + readingEmptyStlContainerError(tok); + } else + empty.erase(tok->varId()); } else if (tok->strAt(-1) == "=") { // Assignment (RHS) if (!noerror) diff --git a/test/teststl.cpp b/test/teststl.cpp index de56bb382..1e0a5b09e 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2885,8 +2885,7 @@ private: " for(auto i = v.cbegin();\n" " i != v.cend(); ++i) {}\n" "}", true); - ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Reading from empty STL container 'v'\n" - "[test.cpp:4]: (style, inconclusive) Reading from empty STL container 'v'\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (style, inconclusive) Reading from empty STL container 'v'\n", errout.str()); check("void f(std::set v) {\n" " v.clear();\n" @@ -2961,6 +2960,15 @@ private: " std::vector vec;\n" "};", true); ASSERT_EQUALS("[test.cpp:6]: (style, inconclusive) Reading from empty STL container 'vec'\n", errout.str()); + + // #7560 + check("std::vector test;\n" + "std::vector::iterator it;\n" + "void Reset() {\n" + " test.clear();\n" + " it = test.end();\n" + "}"); + ASSERT_EQUALS("", errout.str()); } };