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:
parent
d8e282fe76
commit
5334aaa25f
|
@ -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;
|
||||||
|
|
|
@ -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,16 +1036,15 @@ 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"
|
||||||
" { }\n"
|
" { }\n"
|
||||||
" 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,53 +1971,45 @@ 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"
|
||||||
"void b() {\n"
|
"void b() {\n"
|
||||||
" 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"
|
||||||
" char buf[10];\n"
|
" char buf[10];\n"
|
||||||
" a(buf);\n"
|
" a(buf);\n"
|
||||||
" buf[1] = buf[0];\n"
|
" buf[1] = buf[0];\n"
|
||||||
"}");
|
"}");
|
||||||
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,20 +2031,14 @@ 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"
|
||||||
"}").c_str());
|
"}").c_str());
|
||||||
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"
|
||||||
|
|
Loading…
Reference in New Issue