diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 093fd478d..afdee8834 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3456,6 +3456,16 @@ static bool hasContainerSizeGuard(const Token *tok, unsigned int containerId) return false; } +static bool isContainerSizeChangedByFunction(const Token *tok) +{ + const Token *parent = tok->astParent(); + if (parent && parent->str() == "&") + parent = parent->astParent(); + while (parent && parent->str() == ",") + parent = parent->astParent(); + return parent && Token::Match(parent->previous(), "%name% ("); +} + static void valueFlowContainerReverse(const Token *tok, unsigned int containerId, const ValueFlow::Value &value, const Settings *settings) { while (nullptr != (tok = tok->previous())) { @@ -3465,6 +3475,8 @@ static void valueFlowContainerReverse(const Token *tok, unsigned int containerId continue; if (Token::Match(tok, "%name% =")) break; + if (isContainerSizeChangedByFunction(tok)) + break; if (!tok->valueType() || !tok->valueType()->container) break; if (Token::Match(tok, "%name% . %name% (") && tok->valueType()->container->getAction(tok->strAt(2)) != Library::Container::Action::NO_ACTION) @@ -3483,6 +3495,8 @@ static void valueFlowContainerForward(const Token *tok, unsigned int containerId continue; if (Token::Match(tok, "%name% =")) break; + if (isContainerSizeChangedByFunction(tok)) + break; if (!tok->valueType() || !tok->valueType()->container) break; if (Token::Match(tok, "%name% . %name% (") && tok->valueType()->container->getAction(tok->strAt(2)) != Library::Container::Action::NO_ACTION) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 83d08a27b..015f39e0b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3343,6 +3343,14 @@ private: " s.size();\n" "}"; ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "s . size"), 3)); + + // valueFlowContainerForward, function call + code = "void f() {\n" + " std::list x;\n" + " f(x);\n" + " x.front();\n" // <- unknown container size + "}"; + ASSERT(tokenValues(code, "x . front").empty()); } };