diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp
index a74685c39..c830e76c4 100644
--- a/lib/valueflow.cpp
+++ b/lib/valueflow.cpp
@@ -3623,11 +3623,18 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger
if (!Token::Match(parent, ". %name% ("))
continue;
+ bool isContainerOfPointers = true;
+ const Token* containerTypeToken = tok->valueType()->containerTypeToken;
+ if (containerTypeToken) {
+ ValueType vt = ValueType::parseDecl(containerTypeToken, settings);
+ isContainerOfPointers = vt.pointer > 0;
+ }
+
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 931fdc73f..e00595055 100644
--- a/test/teststl.cpp
+++ b/test/teststl.cpp
@@ -4164,6 +4164,40 @@ 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());
+
+ 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());
+
+ check("struct A {};\n"
+ "void f() {\n"
+ " std::vector> v;\n"
+ " std::shared_ptr a = std::make_shared();\n"
+ " v.push_back(a);\n"
+ " std::shared_ptr b = v.back();\n"
+ " v.pop_back();\n"
+ " delete b;\n"
+ "}\n" ,true);
+ ASSERT_EQUALS("", errout.str());
}
void invalidContainerLoop() {