Fix issue 9796: False positive: lifetime, pointer item is not deallocated by pop_back
This commit is contained in:
parent
62702a6816
commit
423dcfd005
|
@ -3623,11 +3623,17 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger
|
||||||
if (!Token::Match(parent, ". %name% ("))
|
if (!Token::Match(parent, ". %name% ("))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool isContainerOfPointers = true;
|
||||||
|
const Token* containerTypeToken = tok->valueType()->containerTypeToken;
|
||||||
|
if (containerTypeToken && Token::simpleMatch(containerTypeToken->previous(), "<") && containerTypeToken->previous()->link()) {
|
||||||
|
isContainerOfPointers = Token::simpleMatch(containerTypeToken->previous()->link()->previous(), "*");
|
||||||
|
}
|
||||||
|
|
||||||
LifetimeStore ls;
|
LifetimeStore ls;
|
||||||
|
|
||||||
if (astIsIterator(parent->tokAt(2)))
|
if (astIsIterator(parent->tokAt(2)))
|
||||||
ls = LifetimeStore{tok, "Iterator to container is created here.", ValueFlow::Value::LifetimeKind::Iterator};
|
ls = LifetimeStore{tok, "Iterator to container is created here.", ValueFlow::Value::LifetimeKind::Iterator};
|
||||||
else if (astIsPointer(parent->tokAt(2)) || Token::Match(parent->next(), "data|c_str"))
|
else if ((astIsPointer(parent->tokAt(2)) && !isContainerOfPointers) || Token::Match(parent->next(), "data|c_str"))
|
||||||
ls = LifetimeStore{tok, "Pointer to container is created here.", ValueFlow::Value::LifetimeKind::Object};
|
ls = LifetimeStore{tok, "Pointer to container is created here.", ValueFlow::Value::LifetimeKind::Object};
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -4164,6 +4164,18 @@ private:
|
||||||
" v.push_back(\"y\");\n"
|
" v.push_back(\"y\");\n"
|
||||||
"}\n",true);
|
"}\n",true);
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// #9796
|
||||||
|
check("struct A {};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" std::vector<A *> v;\n"
|
||||||
|
" A *a = new A();\n"
|
||||||
|
" v.push_back(a);\n"
|
||||||
|
" A *b = v.back();\n"
|
||||||
|
" v.pop_back();\n"
|
||||||
|
" delete b;\n"
|
||||||
|
"}\n" ,true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidContainerLoop() {
|
void invalidContainerLoop() {
|
||||||
|
|
Loading…
Reference in New Issue