Refactorization:

- Removed a few unit tests of old uninitialized variable checking expecting other results than same test for new checking
- A few tweaks to new uninitvar checking to improve results when run on tests for old check
- switched some (TODO) tests to new check if the TODO is fixed
This commit is contained in:
PKEuS 2015-01-21 16:17:58 +01:00
parent d8e282fe76
commit 5334aaa25f
2 changed files with 61 additions and 101 deletions

View File

@ -1671,7 +1671,7 @@ void CheckUninitVar::checkRhs(const Token *tok, const Variable &var, bool alloc,
bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool alloc) const bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool alloc) const
{ {
if (!alloc && vartok->previous()->str() == "return") if (!alloc && vartok->previous()->str() == "return" && vartok->strAt(1) != "=")
return true; return true;
// Passing variable to typeof/__alignof__ // Passing variable to typeof/__alignof__
@ -1690,7 +1690,10 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
tok2 = tok2->tokAt(2); tok2 = tok2->tokAt(2);
if (Token::Match(tok2, "[,)]")) if (Token::Match(tok2, "[,)]"))
return false; return false;
} else if (pointer && Token::Match(vartok, "%var% . %var% (")) {
return true;
} }
bool assignment = false; bool assignment = false;
const Token* parent = vartok->astParent(); const Token* parent = vartok->astParent();
while (parent) { while (parent) {
@ -1750,9 +1753,11 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
} }
if (Token::Match(vartok->previous(), "++|--|%cop%")) { if (Token::Match(vartok->previous(), "++|--|%cop%")) {
if (_tokenizer->isCPP() && vartok->previous()->str() == ">>") { if (_tokenizer->isCPP() && Token::Match(vartok->previous(), ">>|<<")) {
// assume that variable is initialized if (Token::Match(vartok->previous()->astOperand1(), ">>|<<"))
return false; return false; // Looks like stream operator
const Variable *var = vartok->tokAt(-2)->variable();
return (var && var->typeStartToken()->isStandardType());
} }
// is there something like: ; "*((&var ..expr.. =" => the variable is assigned // is there something like: ; "*((&var ..expr.. =" => the variable is assigned
@ -1810,11 +1815,6 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
return true; return true;
} }
if (pointer && Token::Match(vartok, "%var% . %var% (")) {
const Function *function = vartok->tokAt(2)->function();
return (!function || !function->isStatic());
}
if (_tokenizer->isCPP() && Token::Match(vartok->next(), "<<|>>")) { if (_tokenizer->isCPP() && Token::Match(vartok->next(), "<<|>>")) {
// Is this calculation done in rhs? // Is this calculation done in rhs?
const Token *tok = vartok; const Token *tok = vartok;

View File

@ -340,20 +340,20 @@ private:
// Unknown types // Unknown types
{ {
checkUninitVar("void a()\n" checkUninitVar2("void a()\n"
"{\n" "{\n"
" A ret;\n" " A ret;\n"
" return ret;\n" " return ret;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("void a()\n" checkUninitVar2("void a()\n"
"{\n" "{\n"
" A ret;\n" " A ret;\n"
" return ret;\n" " return ret;\n"
"}\n", "}\n",
"test.c"); "test.c");
TODO_ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ret\n", "", errout.str()); ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ret\n", errout.str());
// #3916 - avoid false positive // #3916 - avoid false positive
checkUninitVar("void f(float x) {\n" checkUninitVar("void f(float x) {\n"
@ -389,16 +389,6 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #5255
checkUninitVar("struct Element {\n"
" static void abcd() {}\n"
"};\n"
"void a() {\n"
" Element *e;\n"
" e->abcd();\n"
"}");
ASSERT_EQUALS("", errout.str());
// Handling >> and << // Handling >> and <<
{ {
checkUninitVar("int a() {\n" checkUninitVar("int a() {\n"
@ -1046,7 +1036,7 @@ private:
" }\n" " }\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("void f(int x) {\n" checkUninitVar2("void f(int x) {\n"
" const PoolItem* pItem;\n" " const PoolItem* pItem;\n"
" while (x > 0) {\n" " while (x > 0) {\n"
" if (*pItem != rPool)\n" " if (*pItem != rPool)\n"
@ -1054,8 +1044,7 @@ private:
" x--;\n" " x--;\n"
" }\n" " }\n"
"}"); "}");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", errout.str());
"", errout.str());
// #2231 - conditional initialization in loop.. // #2231 - conditional initialization in loop..
checkUninitVar("int foo(char *a) {\n" checkUninitVar("int foo(char *a) {\n"
@ -1830,13 +1819,6 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: f\n", errout.str());
checkUninitVar("void f()\n"
"{\n"
" int i;\n"
" x(i+2);\n"
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar2("void f()\n" checkUninitVar2("void f()\n"
"{\n" "{\n"
" int i;\n" " int i;\n"
@ -1873,14 +1855,6 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
checkUninitVar("int foo(int x) { return x; }\n"
"void f2()\n"
"{\n"
" int x;\n"
" foo(x);\n"
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar2("int foo(int x) { return x; }\n" checkUninitVar2("int foo(int x) { return x; }\n"
"void f2()\n" "void f2()\n"
"{\n" "{\n"
@ -1997,7 +1971,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2775 - uninitialized struct pointer in subfunction // #2775 - uninitialized struct pointer in subfunction
checkUninitVar("void a(struct Fred *fred) {\n" checkUninitVar2("void a(struct Fred *fred) {\n"
" fred->x = 0;\n" " fred->x = 0;\n"
"}\n" "}\n"
"\n" "\n"
@ -2005,11 +1979,10 @@ private:
" struct Fred *p;\n" " struct Fred *p;\n"
" a(p);\n" " a(p);\n"
"}"); "}");
// TODO: See #2946 ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: p\n", errout.str());
TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: p\n", "", errout.str());
// #2946 - FP array is initialized in subfunction // #2946 - FP array is initialized in subfunction
checkUninitVar("void a(char *buf) {\n" checkUninitVar2("void a(char *buf) {\n"
" buf[0] = 0;\n" " buf[0] = 0;\n"
"}\n" "}\n"
"void b() {\n" "void b() {\n"
@ -2020,30 +1993,23 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #3159 - initialization by function // #3159 - initialization by function
checkUninitVar("static int isnumber(const char *arg) {\n" checkUninitVar2("static int isnumber(const char *arg) {\n"
" char *p;\n" " char *p;\n"
" return strtod(arg, &p) != 0 || p != arg;\n" " return strtod(arg, &p) != 0 || p != arg;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("static int isnumber(const char *arg) {\n" checkUninitVar2("static int isnumber(const char *arg) {\n"
" char *p;\n" " char *p;\n"
" return strtod(&arg) != 0 || p != arg;\n" " return strtod(&arg) != 0 || p != arg;\n"
"}"); "}");
TODO_ASSERT_EQUALS("error", "", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
} }
// valid and invalid use of 'int a(int x) { return x + x; }' // valid and invalid use of 'int a(int x) { return x + x; }'
void func_uninit_var() { void func_uninit_var() {
const std::string funca("int a(int x) { return x + x; }"); const std::string funca("int a(int x) { return x + x; }");
checkUninitVar((funca +
"void b() {\n"
" int x;\n"
" a(x);\n"
"}").c_str());
ASSERT_EQUALS("", errout.str());
checkUninitVar2((funca + checkUninitVar2((funca +
"void b() {\n" "void b() {\n"
" int x;\n" " int x;\n"
@ -2065,7 +2031,7 @@ private:
const std::string funca("void a(int *p) { *p = 0; }"); const std::string funca("void a(int *p) { *p = 0; }");
// ok - initialized pointer // ok - initialized pointer
checkUninitVar((funca + checkUninitVar2((funca +
"void b() {\n" "void b() {\n"
" int buf[10];\n" " int buf[10];\n"
" a(buf);\n" " a(buf);\n"
@ -2073,12 +2039,6 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// not ok - uninitialized pointer // not ok - uninitialized pointer
checkUninitVar((funca +
"void b() {\n"
" int *p;\n"
" a(p);\n"
"}").c_str());
ASSERT_EQUALS("", errout.str());
checkUninitVar2((funca + checkUninitVar2((funca +
"void b() {\n" "void b() {\n"
" int *p;\n" " int *p;\n"