diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 08928f535..26f49d25c 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1338,28 +1338,31 @@ void CheckUninitVar::valueFlowUninit() tok = tok->linkAt(1); continue; } - if (!tok->variable()) + if (!tok->variable() && !tok->isUnaryOp("*")) continue; auto v = std::find_if(tok->values().begin(), tok->values().end(), std::mem_fn(&ValueFlow::Value::isUninitValue)); if (v == tok->values().end()) continue; if (v->isInconclusive()) continue; - if (!isVariableUsage(tok, tok->variable()->isPointer(), tok->variable()->isArray() ? ARRAY : NO_ALLOC)) - continue; if (v->indirect > 1 || v->indirect < 0) continue; - bool unknown; - const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); - if (v->indirect == 1 && !deref) - continue; - const bool uninitderef = deref && v->indirect == 0; - const bool isleaf = isLeafDot(tok) || uninitderef; - if (Token::Match(tok->astParent(), ". %var%") && !isleaf) - continue; + bool uninitderef = false; + if (tok->variable()) { + if (!isVariableUsage(tok, tok->variable()->isPointer(), tok->variable()->isArray() ? ARRAY : NO_ALLOC)) + continue; + bool unknown; + const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); + if (v->indirect == 1 && !deref) + continue; + uninitderef = deref && v->indirect == 0; + const bool isleaf = isLeafDot(tok) || uninitderef; + if (Token::Match(tok->astParent(), ". %var%") && !isleaf) + continue; + } if (!Token::Match(tok->astParent(), ". %name% (") && !uninitderef && isVariableChanged(tok, v->indirect, mSettings, mTokenizer->isCPP())) continue; - uninitvarError(tok, tok->str(), v->errorPath); + uninitvarError(tok, tok->expressionString(), v->errorPath); const Token * nextTok = tok; while (Token::simpleMatch(nextTok->astParent(), ".")) nextTok = nextTok->astParent(); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index a16b59f3d..c01964890 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -4307,6 +4307,32 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: pcdata\n", errout.str()); + // # 9293 + valueFlowUninit("struct S {\n" + " int x;\n" + " int y;\n" + "};\n" + "\n" + "void f() {\n" + " struct S s1;\n" + " int * x = &s1.x;\n" + " struct S s2 = {*x, 0}; \n" + "}\n"); + ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str()); + + valueFlowUninit("struct S {\n" + " int x;\n" + " int y;\n" + "};\n" + "\n" + "void f() {\n" + " struct S s1;\n" + " struct S s2;\n" + " int * x = &s1.x;\n" + " s2.x = *x; \n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str()); + valueFlowUninit("void f(bool * x) {\n" " *x = false;\n" "}\n"