diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e8c2eee4971..d97cd4c62a7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1792,11 +1792,12 @@ static bool isDifferentType(const Token* src, const Token* dst) } else { std::pair decl = Token::typeDecl(src); std::pair parentdecl = Token::typeDecl(dst); - if (isNotEqual(decl, parentdecl)) + const bool isCpp = (src && src->isCpp()) || (dst && dst->isCpp()); + if (isNotEqual(decl, parentdecl) && !(isCpp && (Token::simpleMatch(decl.first, "auto") || Token::simpleMatch(parentdecl.first, "auto")))) return true; - if (isNotEqual(decl, dst->valueType(), dst->isCpp())) + if (isNotEqual(decl, dst->valueType(), isCpp)) return true; - if (isNotEqual(parentdecl, src->valueType(), src->isCpp())) + if (isNotEqual(parentdecl, src->valueType(), isCpp)) return true; } return false; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 3ceb711c6de..fe43f582325 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2864,6 +2864,13 @@ class TestAutoVariables : public TestFixture { " std::cerr << str;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("auto f() {\n" // #11420 + " std::vector x;\n" + " std::vector::iterator it = x.begin();\n" + " return it;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning iterator to local container 'x' that will be invalid when returning.\n", errout_str()); } void danglingLifetimeContainerView() @@ -3083,6 +3090,14 @@ class TestAutoVariables : public TestFixture { ASSERT_EQUALS( "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'a' that will be invalid when returning.\n", errout_str()); + + check("std::string_view f() {\n" // #10995 + " char a[10]{};\n" + " return a;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'a' that will be invalid when returning.\n", + errout_str()); } void danglingLifetimeUniquePtr()