diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 3cac50b24..1ec1994a2 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1378,7 +1378,7 @@ private: CheckUninitVar *c = dynamic_cast(*it); if (c && c->varId == varid) { - if (!c->alloc) + if (c->pointer && !c->alloc) { CheckOther *checkOther = dynamic_cast(c->owner); if (checkOther) @@ -1424,6 +1424,10 @@ private: if (mode == 2 && !c->pointer) continue; + // mode 3 : using dead pointer is invalid. + if (mode == 3 && (!c->pointer || c->alloc)) + continue; + CheckOther *checkOther = dynamic_cast(c->owner); if (checkOther) { @@ -1472,6 +1476,17 @@ private: use(foundError, checks, tok, 2); } + /** + * Using variable.. if it's a dead pointer the usage is invalid. + * @param foundError this is set to true if an error is found + * @param checks all available checks + * @param tok variable token + */ + static void use_dead_pointer(bool &foundError, std::list &checks, const Token *tok) + { + use(foundError, checks, tok, 3); + } + const Token *parse(const Token &tok, bool &foundError, std::list &checks) const { // Variable declaration.. @@ -1583,6 +1598,9 @@ private: else if (tok2->varId()) { + if (Token::Match(tok2->tokAt(-2), "[(,] *")) + use_dead_pointer(foundError, checks, tok2); + // it is possible that the variable is initialized here ExecutionPath::bailOutVar(checks, tok2->varId()); } diff --git a/test/testother.cpp b/test/testother.cpp index abe032798..535feb6ae 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1006,6 +1006,13 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str()); + checkUninitVar("static void foo()\n" + "{\n" + " int *x;\n" + " int &y(*x);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str()); + checkUninitVar("static int foo()\n" "{\n" " int ret;\n"