diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 74e923f3d..312740f9f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4629,6 +4629,17 @@ static bool isConvertedToView(const Token* tok, const Settings* settings) }); } +static bool isContainerOfPointers(const Token* tok, const Settings* settings) +{ + if (!tok) + { + return true; + } + + ValueType vt = ValueType::parseDecl(tok, settings, true); // TODO: set isCpp + return vt.pointer > 0; +} + static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, ErrorLogger *errorLogger, const Settings *settings) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { @@ -4781,13 +4792,6 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro if (!Token::Match(parent, ". %name% (")) continue; - bool isContainerOfPointers = true; - const Token* containerTypeToken = tok->valueType()->containerTypeToken; - if (containerTypeToken) { - ValueType vt = ValueType::parseDecl(containerTypeToken, settings, true); // TODO: set isCpp - isContainerOfPointers = vt.pointer > 0; - } - ValueFlow::Value master; master.valueType = ValueFlow::Value::ValueType::LIFETIME; master.lifetimeScope = ValueFlow::Value::LifetimeScope::Local; @@ -4795,7 +4799,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro if (astIsIterator(parent->tokAt(2))) { master.errorPath.emplace_back(parent->tokAt(2), "Iterator to container is created here."); master.lifetimeKind = ValueFlow::Value::LifetimeKind::Iterator; - } else if ((astIsPointer(parent->tokAt(2)) && !isContainerOfPointers) || + } else if ((astIsPointer(parent->tokAt(2)) && !isContainerOfPointers(tok->valueType()->containerTypeToken, settings)) || Token::Match(parent->next(), "data|c_str")) { master.errorPath.emplace_back(parent->tokAt(2), "Pointer to container is created here."); master.lifetimeKind = ValueFlow::Value::LifetimeKind::Object; @@ -4816,7 +4820,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro } } else if (astIsContainerView(tok)) { for (const ValueFlow::Value& v : tok->values()) { - if (!v.isLifetimeValue()) + if (!v.isLocalLifetimeValue()) continue; if (!v.tokvalue) continue; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index ad58f32c3..189f23e21 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4194,6 +4194,27 @@ private: " f(bar);\n" "}\n"); ASSERT_EQUALS("[test.cpp:10]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str()); + + check("void f(std::string_view text);\n" // #11508 + "void g() {\n" + " std::string teststr;\n" + " f(teststr);" + "}\n" + "void f(std::string_view text) {" + " g(text.data());\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::span data);\n" // #11508 + "void g() {\n" + " std::vector v;\n" + " f(v);" + "}\n" + "void f(std::span data) {" + " g(data.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } void deadPointer() {