From 8e3e634ce0e99e8808790bed67f82b5f1005dd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 14 Dec 2011 18:28:30 +0100 Subject: [PATCH] Uninitialized variables: Detect more errors. Ticket: #3369 --- lib/checkuninitvar.cpp | 25 ++++++++++++++++++++----- lib/checkuninitvar.h | 1 + test/testuninitvar.cpp | 13 +++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 4d8a7cc4b..8f6bc787f 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1078,7 +1078,8 @@ 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) { - // TODO: better checks if this is initialization or usage + if (isVariableUsage(tok2)) + uninitvarError(tok2, tok2->str()); return true; } } @@ -1124,10 +1125,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int return true; // Use variable - if (tok->previous()->str() == "return") - uninitvarError(tok, tok->str()); - - else if (Token::Match(tok->next(), "++|--|%op%")) + if (isVariableUsage(tok)) uninitvarError(tok, tok->str()); else @@ -1139,6 +1137,23 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int return ret; } +bool CheckUninitVar::isVariableUsage(const Token *vartok) const +{ + if (vartok->previous()->str() == "return") + return true; + + if (Token::Match(vartok->next(), "++|--|%op%")) + return true; + + if (Token::Match(vartok->previous(), "++|--|%op%")) { + if (vartok->previous()->str() != "&" || !Token::Match(vartok->tokAt(-2), "[(,]")) { + return true; + } + } + + return false; +} + void CheckUninitVar::uninitstringError(const Token *tok, const std::string &varname, bool strncpy_) { diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 734487b0a..ce756a272 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -61,6 +61,7 @@ public: /** Check for uninitialized variables */ void check(); bool checkScopeForVariable(const Token *tok, const unsigned int varid); + bool isVariableUsage(const Token *vartok) 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 e6fef5f26..91d77bafc 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1713,6 +1713,19 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); + checkUninitVar2("void f() {\n" + " int x;\n" + " int y = 3 & x;\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); + + // using uninit var in condition + checkUninitVar2("void f() {\n" + " int x;\n" + " if (1 == (3 & x)) { }\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); + // conditional initialization checkUninitVar2("void f() {\n" " int x;\n"