diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 54a927bab1f..ee4264e958d 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1712,10 +1712,8 @@ static std::vector getLifetimeTokens(const Token* tok, for (ValueFlow::LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, pred, settings, depth - returns.size())) { const Token* argvarTok = lt.token; const Variable* argvar = argvarTok->variable(); - if (!argvar) - continue; const Token* argTok = nullptr; - if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) { + if (argvar && argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) { const int n = getArgumentPos(argvar, f); if (n < 0) return std::vector {}; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 32fa439e4b5..3fd722ebbe1 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4356,6 +4356,35 @@ class TestAutoVariables : public TestFixture { " *p = ret;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct A {\n" + " int val=42;\n" + " const A& Get() const & {\n" + " return *this;\n" + " }\n" + "};\n" + "const A *ptr;\n" + "int main() {\n" + " ptr = &A().Get();\n" + " return ptr->val;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:9] -> [test.cpp:9] -> [test.cpp:9] -> [test.cpp:10]: (error) Using pointer that is a temporary.\n", + errout_str()); + + check("struct A {\n" + " int val = 42;\n" + " const A& Get() const {\n" + " return *this;\n" + " }\n" + "};\n" + "int main() {\n" + " const A& r = A().Get();\n" + " return r.val;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:8] -> [test.cpp:4] -> [test.cpp:8] -> [test.cpp:9]: (error) Using reference to dangling temporary.\n", + errout_str()); } void invalidLifetime() {