diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index d46cb3a17..5dde8be54 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1535,10 +1535,14 @@ void CheckStl::readingEmptyStlContainer() if (i->type != Scope::eFunction) continue; + const Token* restartTok = nullptr; for (const Token *tok = i->classStart->next(); tok != i->classEnd; tok = tok->next()) { - if (Token::Match(tok, "for|while|do|}")) { // Loops and end of scope clear the sets. + if (Token::Match(tok, "for|while")) { // Loops and end of scope clear the sets. + restartTok = tok->linkAt(1); // Check condition to catch looping over empty containers + } else if (tok == restartTok || Token::Match(tok, "do|}")) { empty_map.clear(); empty_nonmap.clear(); + restartTok = nullptr; } if (!tok->varId()) diff --git a/test/teststl.cpp b/test/teststl.cpp index 00ae0ceab..0419252e7 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2664,6 +2664,13 @@ private: " std::string strValue2 = CMap[1];\n" "}\n", true); ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Reading from empty STL container\n", errout.str()); + + // #4306 + check("void f(std::vector v) {\n" + " v.clear();\n" + " for(int i = 0; i < v.size(); i++) { cout << v[i]; }\n" + "}", true); + ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Reading from empty STL container\n", errout.str()); } };