diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 32b06eb96e4..766ccd861e0 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -586,7 +586,7 @@ struct ValueFlowAnalyzer : Analyzer { } else if (ref->isUnaryOp("*") && !match(ref->astOperand1())) { const Token* lifeTok = nullptr; for (const ValueFlow::Value& v:ref->astOperand1()->values()) { - if (!v.isLocalLifetimeValue()) + if (!v.isLocalLifetimeValue() && !v.isSubFunctionLifetimeValue()) continue; if (lifeTok) return Action::None; @@ -1046,7 +1046,12 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer { } bool match(const Token* tok) const override { - return values.count(tok->varId()) > 0; + if (tok->varId() == 0) + return false; + return values.count(tok->varId()) > 0 || + std::any_of(values.begin(), values.end(), [&](const std::pair& p) { + return p.second.isUninitValue() && p.second.tokvalue->varId() == tok->varId(); + }); } ProgramState getProgramState() const override { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e19ea083fbc..89781b14c72 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -4387,6 +4387,17 @@ class TestUninitVar : public TestFixture { " return f(i, 0);\n" "}"); ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:4]: (warning) Uninitialized variable: i\n", errout_str()); + + valueFlowUninit("char *f (char *b) {\n" // #12612 + " char* p = b;\n" + " *p = '\\0';\n" + " return b;\n" + "}\n" + "void g() {\n" + " char a[24];\n" + " f(a);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void uninitStructMember() { // struct members