diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 81e945565..8db8a56cf 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2651,8 +2651,11 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, const Token * ptok = tok2; while (Token::Match(ptok->astParent(), ".|::|[")) ptok = ptok->astParent(); + int pindirect = indirect; + if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next())) + pindirect = 1; bool inconclusive = false; - bool isChanged = isVariableChangedByFunctionCall(ptok, indirect, settings, &inconclusive); + bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings, &inconclusive); isChanged |= inconclusive; if (isChanged) return true; @@ -3257,6 +3260,8 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings continue; if (arg->isReference()) return ExprUsage::PassedByReference; + if (arg->isPointer() && indirect == 1) + return ExprUsage::PassedByReference; } if (!args.empty() && indirect == 0 && !addressOf) return ExprUsage::Used; @@ -3301,6 +3306,8 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, parent = parent->astParent(); if (Token::Match(parent, "%assign%") && (astIsRHS(tok) || astIsLHS(parent->astOperand1()))) return ExprUsage::NotUsed; + if (Token::Match(parent, "++|--")) + return ExprUsage::NotUsed; if (parent->isConstOp()) return ExprUsage::NotUsed; if (parent->isCast()) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 3ab800b3d..f797c1897 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1642,12 +1642,7 @@ void CheckUninitVar::valueFlowUninit() const bool isarray = tok->variable()->isArray(); if (isarray && tok->variable()->isMember()) continue; // Todo: this is a bailout - const bool ispointer = astIsPointer(tok) && !isarray; const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); - if (ispointer && v->indirect == 1 && !deref) - continue; - if (isarray && !deref) - continue; uninitderef = deref && v->indirect == 0; const bool isleaf = isLeafDot(tok) || uninitderef; if (!isleaf && Token::Match(tok->astParent(), ". %name%") && (tok->astParent()->next()->varId() || tok->astParent()->next()->isEnumerator())) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 3b4c548c7..397cefa1e 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6313,7 +6313,7 @@ private: " f(a, b);\n" " printf(\"%s\", a);\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); valueFlowUninit("void usage(const char *);\n" // #10330 "int main(int argc, char* argv[]) {\n" @@ -6334,6 +6334,14 @@ private: " if (pwd == NULL) {}\n" "}"); ASSERT_EQUALS("[test.cpp:15] -> [test.cpp:17]: (warning) Uninitialized variable: pwd\n", errout.str()); + + // #12033 + valueFlowUninit("void g(const char*p);\n" + "void f() {\n" + " char buf[10];\n" + " g(buf);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: buf\n", errout.str()); } void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value @@ -6385,7 +6393,7 @@ private: " someType_t gVar;\n" " bar(&gVar);\n" "}"); - ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:5]: (warning) Uninitialized variable: p->flags\n", errout.str()); + ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: &gVar\n", errout.str()); valueFlowUninit("typedef struct\n" "{\n" @@ -6917,7 +6925,7 @@ private: " foo(123, &abc);\n" " return abc.b;\n" "}"); - ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: abc.b\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: &abc\n", errout.str()); valueFlowUninit("struct ABC { int a; int b; int c; };\n" "void foo() {\n"