From 423dcfd005d2ba1eff75039d77c18601328c4090 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 15 Jul 2020 12:22:36 -0500 Subject: [PATCH] Fix issue 9796: False positive: lifetime, pointer item is not deallocated by pop_back --- lib/valueflow.cpp | 8 +++++++- test/teststl.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 271429172..57dadab82 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3623,11 +3623,17 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger if (!Token::Match(parent, ". %name% (")) 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; if (astIsIterator(parent->tokAt(2))) 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}; else continue; diff --git a/test/teststl.cpp b/test/teststl.cpp index e9e929a92..ca054dfaf 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4164,6 +4164,18 @@ private: " v.push_back(\"y\");\n" "}\n",true); ASSERT_EQUALS("", errout.str()); + + // #9796 + check("struct A {};\n" + "void f() {\n" + " std::vector 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() {