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;
|
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)
|
static void valueFlowContainerReverse(const Token *tok, unsigned int containerId, const ValueFlow::Value &value, const Settings *settings)
|
||||||
{
|
{
|
||||||
while (nullptr != (tok = tok->previous())) {
|
while (nullptr != (tok = tok->previous())) {
|
||||||
|
@ -3465,6 +3475,8 @@ static void valueFlowContainerReverse(const Token *tok, unsigned int containerId
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%name% ="))
|
if (Token::Match(tok, "%name% ="))
|
||||||
break;
|
break;
|
||||||
|
if (isContainerSizeChangedByFunction(tok))
|
||||||
|
break;
|
||||||
if (!tok->valueType() || !tok->valueType()->container)
|
if (!tok->valueType() || !tok->valueType()->container)
|
||||||
break;
|
break;
|
||||||
if (Token::Match(tok, "%name% . %name% (") && tok->valueType()->container->getAction(tok->strAt(2)) != Library::Container::Action::NO_ACTION)
|
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;
|
continue;
|
||||||
if (Token::Match(tok, "%name% ="))
|
if (Token::Match(tok, "%name% ="))
|
||||||
break;
|
break;
|
||||||
|
if (isContainerSizeChangedByFunction(tok))
|
||||||
|
break;
|
||||||
if (!tok->valueType() || !tok->valueType()->container)
|
if (!tok->valueType() || !tok->valueType()->container)
|
||||||
break;
|
break;
|
||||||
if (Token::Match(tok, "%name% . %name% (") && tok->valueType()->container->getAction(tok->strAt(2)) != Library::Container::Action::NO_ACTION)
|
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"
|
" s.size();\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "s . size"), 3));
|
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