diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5ccae4187..d570cc0a1 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4027,6 +4027,19 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger else if (Token::Match(tok, "%name% (")) { valueFlowLifetimeFunction(tok, tokenlist, errorLogger, settings); } + // Unique pointer lifetimes + else if (isUniqueSmartPointer(tok) && astIsLHS(tok) && Token::simpleMatch(tok->astParent(), ". get ( )")) { + Token* ptok = tok->astParent()->tokAt(2); + ErrorPath errorPath = {{ptok, "Raw pointer to smart pointer created here."}}; + ValueFlow::Value value; + value.valueType = ValueFlow::Value::ValueType::LIFETIME; + value.lifetimeScope = ValueFlow::Value::LifetimeScope::Local; + value.lifetimeKind = ValueFlow::Value::LifetimeKind::SubObject; + value.tokvalue = tok; + value.errorPath = errorPath; + setTokenValue(ptok, value, tokenlist->getSettings()); + valueFlowForwardLifetime(ptok, tokenlist, errorLogger, settings); + } // Check variables else if (tok->variable()) { ErrorPath errorPath; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index e1db3dab5..708525bcb 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -142,6 +142,7 @@ private: TEST_CASE(danglingLifetimeLambda); TEST_CASE(danglingLifetimeContainer); TEST_CASE(danglingLifetimeContainerView); + TEST_CASE(danglingLifetimeUniquePtr); TEST_CASE(danglingLifetime); TEST_CASE(danglingLifetimeFunction); TEST_CASE(danglingLifetimeAggegrateConstructor); @@ -2541,6 +2542,16 @@ private: ASSERT_EQUALS("", errout.str()); } + void danglingLifetimeUniquePtr() + { + check("int* f(std::unique_ptr p) {\n" + " int * rp = p.get();\n" + " return rp;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:2] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning pointer to local variable 'p' that will be invalid when returning.\n", + errout.str()); + } void danglingLifetime() { check("auto f() {\n" " std::vector a;\n"