diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 05fe4523f..cd1b74809 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1268,6 +1268,27 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const return false; } + // is there something like: ; "*((&var ..expr.. =" => the variable is assigned + if (vartok->previous()->str() == "&") { + const Token *tok2 = vartok->tokAt(-2); + if (Token::simpleMatch(tok2,")")) + tok2 = tok2->link()->previous(); + while (tok2 && tok2->str() == "(") + tok2 = tok2->previous(); + while (tok2 && tok2->str() == "*") + tok2 = tok2->previous(); + if (Token::Match(tok2, "[;{}] *")) { + // there is some such code before vartok: "[*]+ [(]* &" + // determine if there is a = after vartok + for (tok2 = vartok; tok2; tok2 = tok2->next()) { + if (Token::Match(tok2, "[;{}]")) + break; + if (tok2->str() == "=") + return false; + } + } + } + if (vartok->previous()->str() != "&" || !Token::Match(vartok->tokAt(-2), "[(,=?:]")) { return true; } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 2167ce886..6a6678378 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1928,6 +1928,12 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + checkUninitVar2("void f() {\n" // #3926 - weird cast. + " int x;\n" + " *(((char *)&x) + 0) = 0;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // using uninit var in condition checkUninitVar2("void f() {\n" " int x;\n"