Unit testing: Improved test coverage for variable usage checking
This commit is contained in:
parent
1fa1ff8d14
commit
4014bd234f
|
@ -435,16 +435,13 @@ public:
|
|||
VariableType type = standard,
|
||||
bool read = false,
|
||||
bool write = false,
|
||||
bool modified = false,
|
||||
unsigned int alias = 0) :
|
||||
bool modified = false) :
|
||||
_name(name),
|
||||
_type(type),
|
||||
_read(read),
|
||||
_write(write),
|
||||
_modified(modified)
|
||||
{
|
||||
if (alias)
|
||||
_aliases.insert(alias);
|
||||
}
|
||||
|
||||
/** variable is used.. set both read+write */
|
||||
|
@ -478,7 +475,7 @@ public:
|
|||
{
|
||||
return _varUsage;
|
||||
}
|
||||
void addVar(const Token *name, VariableType type, bool write_ = false, unsigned int varid = 0);
|
||||
void addVar(const Token *name, VariableType type, bool write_);
|
||||
void read(unsigned int varid);
|
||||
void readAliases(unsigned int varid);
|
||||
void readAll(unsigned int varid);
|
||||
|
@ -543,15 +540,9 @@ void Variables::alias(unsigned int varid1, unsigned int varid2)
|
|||
|
||||
void Variables::addVar(const Token *name,
|
||||
VariableType type,
|
||||
bool write_,
|
||||
unsigned int varid )
|
||||
bool write_)
|
||||
{
|
||||
_varUsage.insert(std::make_pair(name->varId(), VariableUsage(name, type, false, write_, false, varid)));
|
||||
|
||||
VariableUsage *usage = find(varid);
|
||||
|
||||
if (usage)
|
||||
usage->_aliases.insert(name->varId());
|
||||
_varUsage.insert(std::make_pair(name->varId(), VariableUsage(name, type, false, write_, false)));
|
||||
}
|
||||
|
||||
void Variables::read(unsigned int varid)
|
||||
|
@ -750,10 +741,10 @@ static int doAssignment(Variables &variables, const Token *tok, bool pointer)
|
|||
// check for C++ style cast
|
||||
else if (tok->tokAt(2)->str().find("cast") != std::string::npos)
|
||||
{
|
||||
if (tok->tokAt(3)->str() == "const")
|
||||
if (tok->tokAt(4)->str() == "const")
|
||||
offset++;
|
||||
|
||||
if (Token::Match(tok->tokAt(3 + offset), "struct|union"))
|
||||
if (Token::Match(tok->tokAt(4 + offset), "struct|union"))
|
||||
offset++;
|
||||
|
||||
if (tok->tokAt(8 + offset)->str() == "&")
|
||||
|
@ -924,7 +915,7 @@ void CheckOther::functionVariableUsage()
|
|||
|
||||
bool written = tok->tokAt(4)->str() == "=";
|
||||
|
||||
variables.addVar(tok->tokAt(3), type, written, 0);
|
||||
variables.addVar(tok->tokAt(3), type, written);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
|
@ -949,7 +940,7 @@ void CheckOther::functionVariableUsage()
|
|||
|
||||
bool written = tok->tokAt(5)->str() == "=";
|
||||
|
||||
variables.addVar(tok->tokAt(4), type, written, 0);
|
||||
variables.addVar(tok->tokAt(4), type, written);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
|
@ -973,7 +964,7 @@ void CheckOther::functionVariableUsage()
|
|||
|
||||
bool written = tok->tokAt(5)->str() == "=";
|
||||
|
||||
variables.addVar(tok->tokAt(4), type, written, 0);
|
||||
variables.addVar(tok->tokAt(4), type, written);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
|
@ -997,7 +988,7 @@ void CheckOther::functionVariableUsage()
|
|||
|
||||
bool written = tok->tokAt(6)->str() == "=";
|
||||
|
||||
variables.addVar(tok->tokAt(5), type, written, 0);
|
||||
variables.addVar(tok->tokAt(5), type, written);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
|
@ -1026,7 +1017,7 @@ void CheckOther::functionVariableUsage()
|
|||
if (Token::Match(tok->tokAt(5), "%var%"))
|
||||
varid = tok->tokAt(5)->varId();
|
||||
|
||||
variables.addVar(tok->tokAt(3), type, true, varid);
|
||||
variables.addVar(tok->tokAt(3), type, true);
|
||||
|
||||
// check if a local variable is used to initialize this variable
|
||||
if (varid > 0)
|
||||
|
@ -1051,6 +1042,49 @@ void CheckOther::functionVariableUsage()
|
|||
tok = tok->tokAt(6);
|
||||
}
|
||||
|
||||
// const pointer or reference declaration with initialization using constructor
|
||||
// const int * i(j); const int * k(i);
|
||||
else if (Token::Match(tok, "[;{}] const %type% &|* %var% ( %any% ) ;") &&
|
||||
(tok->tokAt(2)->isStandardType() || tok->tokAt(2)->str() == "void"))
|
||||
{
|
||||
Variables::VariableType type;
|
||||
|
||||
if (tok->tokAt(3)->str() == "*")
|
||||
type = Variables::pointer;
|
||||
else
|
||||
type = Variables::reference;
|
||||
|
||||
unsigned int varid = 0;
|
||||
|
||||
// check for aliased variable
|
||||
if (Token::Match(tok->tokAt(6), "%var%"))
|
||||
varid = tok->tokAt(6)->varId();
|
||||
|
||||
variables.addVar(tok->tokAt(4), type, true);
|
||||
|
||||
// check if a local variable is used to initialize this variable
|
||||
if (varid > 0)
|
||||
{
|
||||
Variables::VariableUsage *var = variables.find(varid);
|
||||
|
||||
if (type == Variables::pointer)
|
||||
{
|
||||
variables.use(tok->tokAt(6)->varId());
|
||||
|
||||
if (var && (var->_type == Variables::array ||
|
||||
var->_type == Variables::pointer))
|
||||
var->_aliases.insert(tok->varId());
|
||||
}
|
||||
else
|
||||
{
|
||||
variables.readAll(tok->tokAt(6)->varId());
|
||||
if (var)
|
||||
var->_aliases.insert(tok->varId());
|
||||
}
|
||||
}
|
||||
tok = tok->tokAt(7);
|
||||
}
|
||||
|
||||
// array of pointer or reference declaration with possible initialization
|
||||
// int * p[10]; int * q[10] = { 0 };
|
||||
else if (Token::Match(tok, "[;{}] %type% *|& %var% [ %any% ] ;|="))
|
||||
|
@ -1059,7 +1093,7 @@ void CheckOther::functionVariableUsage()
|
|||
{
|
||||
variables.addVar(tok->tokAt(3),
|
||||
tok->tokAt(2)->str() == "*" ? Variables::pointerArray : Variables::referenceArray,
|
||||
tok->tokAt(7)->str() == "=", false);
|
||||
tok->tokAt(7)->str() == "=");
|
||||
tok = tok->tokAt(6);
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1104,7 @@ void CheckOther::functionVariableUsage()
|
|||
{
|
||||
variables.addVar(tok->tokAt(4),
|
||||
tok->tokAt(3)->str() == "*" ? Variables::pointerArray : Variables::referenceArray,
|
||||
tok->tokAt(8)->str() == "=", false);
|
||||
tok->tokAt(8)->str() == "=");
|
||||
tok = tok->tokAt(7);
|
||||
}
|
||||
|
||||
|
@ -1080,7 +1114,7 @@ void CheckOther::functionVariableUsage()
|
|||
{
|
||||
variables.addVar(tok->tokAt(4),
|
||||
tok->tokAt(3)->str() == "*" ? Variables::pointerArray : Variables::referenceArray,
|
||||
tok->tokAt(8)->str() == "=", false);
|
||||
tok->tokAt(8)->str() == "=");
|
||||
tok = tok->tokAt(6);
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1124,7 @@ void CheckOther::functionVariableUsage()
|
|||
{
|
||||
variables.addVar(tok->tokAt(5),
|
||||
tok->tokAt(4)->str() == "*" ? Variables::pointerArray : Variables::referenceArray,
|
||||
tok->tokAt(9)->str() == "=", false);
|
||||
tok->tokAt(9)->str() == "=");
|
||||
tok = tok->tokAt(7);
|
||||
}
|
||||
|
||||
|
|
|
@ -334,6 +334,65 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int i(a);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int j = 0;\n"
|
||||
" int i(j);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int j = 0;\n"
|
||||
" int & i = j;\n"
|
||||
" j = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int j = 0;\n"
|
||||
" const int & i = j;\n"
|
||||
" j = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int j = 0;\n"
|
||||
" int & i(j);\n"
|
||||
" j = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int j = 0;\n"
|
||||
" const int & i(j);\n"
|
||||
" j = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int * j = 0;\n"
|
||||
" int * i(j);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int * j = 0;\n"
|
||||
" const int * i(j);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" bool i = false;\n"
|
||||
|
@ -396,6 +455,18 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" struct S & i = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" const struct S & i = j;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" undefined * i = 0;\n"
|
||||
|
@ -961,6 +1032,30 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
" char *b = (char *)(&a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
" const char *b = (const char *)&a;\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
" const char *b = (const char *)(&a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
|
@ -969,6 +1064,14 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
" const char *b = static_cast<const char *>(&a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
// a is not a local variable and b is aliased to it (not supported yet)
|
||||
functionVariableUsage("int a;\n"
|
||||
"void foo()\n"
|
||||
|
@ -1037,6 +1140,30 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" char *b = (char *)(a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" const char *b = (const char *)a;\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" const char *b = (const char *)(a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
|
@ -1045,6 +1172,14 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" const char *b = static_cast<const char *>(a);\n"
|
||||
" *b = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"), errout.str());
|
||||
|
||||
functionVariableUsage("int a[10];\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1182,6 +1317,33 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
|
||||
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("struct S { char c[100]; };\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
" char a[100];\n"
|
||||
" const struct S * s = (const struct S *)a;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
|
||||
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("struct S { char c[100]; };\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
" char a[100];\n"
|
||||
" struct S * s = static_cast<struct S *>(a);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
|
||||
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("struct S { char c[100]; };\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
" char a[100];\n"
|
||||
" const struct S * s = static_cast<const struct S *>(a);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
|
||||
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used\n", errout.str());
|
||||
}
|
||||
|
||||
void localvaralias2() // ticket 1637
|
||||
|
|
Loading…
Reference in New Issue