diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 999b9bf69..d0d6e0b88 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1049,16 +1049,31 @@ void CheckUninitVar::check() // only check functions if (func_scope->type == Scope::eFunction) { for (const Token *tok = func_scope->classStart; tok && tok != func_scope->classEnd; tok = tok->next()) { - // Variable declaration.. - if (Token::Match(tok, "[;{}] %type% %var% ;") && tok->next()->isStandardType()) { - checkScopeForVariable(tok->tokAt(3), tok->tokAt(2)->varId()); + + if (Token::Match(tok, "[;{}] %type% !!;")) { + bool stdtype = false; + bool pointer = false; + tok = tok->next(); + while (tok->isName() || tok->str() == "*") { + if (tok->isStandardType()) + stdtype = true; + else if (tok->str() == "*") + pointer = true; + else if (tok->isName() && tok->next()->str() == ";") { + if (stdtype || pointer || _tokenizer->isC()) + checkScopeForVariable(tok->next(), tok->varId(), pointer, NULL); + break; + } else if (!tok->isName()) + break; + tok = tok->next(); + } } } } } } -bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int varid, bool * const possibleInit) +bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int varid, bool ispointer, bool * const possibleInit) { if (varid == 0) return false; @@ -1094,7 +1109,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int const Token * const endToken = tok->next()->link(); for (const Token *tok2 = tok->tokAt(2); tok2 != endToken; tok2 = tok2->next()) { if (tok2->varId() == varid) { - if (!suppressErrors && isVariableUsage(tok2)) + if (!suppressErrors && isVariableUsage(tok2, ispointer)) uninitvarError(tok2, tok2->str()); return true; } @@ -1106,7 +1121,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int tok = tok->next()->link()->next(); bool possibleInitIf(number_of_if > 0); - const bool initif = checkScopeForVariable(tok->next(), varid, &possibleInitIf); + const bool initif = checkScopeForVariable(tok->next(), varid, ispointer, &possibleInitIf); // goto the } tok = tok->link(); @@ -1126,7 +1141,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int tok = tok->tokAt(2); bool possibleInitElse(number_of_if > 0); - const bool initelse = checkScopeForVariable(tok->next(), varid, &possibleInitElse); + const bool initelse = checkScopeForVariable(tok->next(), varid, ispointer, &possibleInitElse); // goto the } tok = tok->link(); @@ -1175,7 +1190,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int // variable is seen.. if (tok->varId() == varid) { // Use variable - if (!suppressErrors && isVariableUsage(tok)) + if (!suppressErrors && isVariableUsage(tok, ispointer)) uninitvarError(tok, tok->str()); else @@ -1187,7 +1202,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int return ret; } -bool CheckUninitVar::isVariableUsage(const Token *vartok) const +bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const { if (vartok->previous()->str() == "return") return true; @@ -1203,6 +1218,10 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok) const } } + bool unknown = false; + if (pointer && CheckNullPointer::isPointerDeRef(vartok, unknown)) + return true; + if (Token::Match(vartok->next(), "++|--|%op%")) return true; diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 108fb63b1..9cf9acf35 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -60,8 +60,8 @@ public: /** Check for uninitialized variables */ void check(); - bool checkScopeForVariable(const Token *tok, const unsigned int varid, bool * const possibleInit=0); - bool isVariableUsage(const Token *vartok) const; + bool checkScopeForVariable(const Token *tok, const unsigned int varid, bool ispointer, bool * const possibleInit); + bool isVariableUsage(const Token *vartok, bool ispointer) const; /** * @brief Uninitialized variables: analyse functions to see how they work with uninitialized variables diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 37a614cf3..23e0c00e7 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1733,6 +1733,12 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); + checkUninitVar2("void f() {\n" + " struct ABC *abc;\n" + " abc->a = 0;\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: abc\n", errout.str()); + // using uninit var in condition checkUninitVar2("void f() {\n" " int x;\n"