valueFlowSizeForward: Bailout when function calls modify the container size
This commit is contained in:
parent
183345a939
commit
55ab842083
|
@ -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)
|
||||
|
|
|
@ -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<int> x;\n"
|
||||
" f(x);\n"
|
||||
" x.front();\n" // <- unknown container size
|
||||
"}";
|
||||
ASSERT(tokenValues(code, "x . front").empty());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue