unused variables: fixed false negatives with the help of the symbol database. ticket: #2317
This commit is contained in:
parent
f73cce9eca
commit
244974a61a
|
@ -1641,10 +1641,31 @@ void CheckOther::functionVariableUsage()
|
|||
else if (var && var->_type == Variables::pointer &&
|
||||
Token::Match(start, "%var% = new|malloc|calloc|g_malloc|kmalloc|vmalloc"))
|
||||
{
|
||||
if (start->strAt(2) == "new" && !start->tokAt(3)->isStandardType())
|
||||
variables.write(varid1);
|
||||
else
|
||||
bool allocate = true;
|
||||
|
||||
if (start->strAt(2) == "new")
|
||||
{
|
||||
// is it a user defined type?
|
||||
if (!start->tokAt(3)->isStandardType())
|
||||
{
|
||||
// lookup the type
|
||||
const SymbolDatabase::SpaceInfo *type = symbolDatabase->findVarType(info, start->tokAt(3));
|
||||
|
||||
// unknown type?
|
||||
if (!type)
|
||||
allocate = false;
|
||||
|
||||
// has default constructor or
|
||||
// has members with unknown type or default constructor
|
||||
else if (type->needInitialization == SymbolDatabase::SpaceInfo::False)
|
||||
allocate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allocate)
|
||||
variables.allocateMemory(varid1);
|
||||
else
|
||||
variables.write(varid1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -957,6 +957,23 @@ SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classD
|
|||
nestedIn->nestedList.push_back(this);
|
||||
}
|
||||
|
||||
bool
|
||||
SymbolDatabase::SpaceInfo::hasDefaultConstructor() const
|
||||
{
|
||||
if (numConstructors)
|
||||
{
|
||||
std::list<Func>::const_iterator func;
|
||||
|
||||
for (func = functionList.begin(); func != functionList.end(); ++func)
|
||||
{
|
||||
if (func->type == Func::Constructor &&
|
||||
func->argDef->link() == func->argDef->next())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get variable list..
|
||||
void SymbolDatabase::SpaceInfo::getVarList()
|
||||
{
|
||||
|
|
|
@ -232,6 +232,8 @@ public:
|
|||
unsigned int getNestedNonFunctions() const;
|
||||
|
||||
bool isBaseClassFunc(const Token *tok);
|
||||
|
||||
bool hasDefaultConstructor() const;
|
||||
};
|
||||
|
||||
bool isMemberVar(const SpaceInfo *info, const Token *tok);
|
||||
|
@ -246,6 +248,14 @@ public:
|
|||
/** @brief Information about all namespaces/classes/structrues */
|
||||
std::list<SpaceInfo *> spaceInfoList;
|
||||
|
||||
/**
|
||||
* @brief find a variable type if it's a user defined type
|
||||
* @param start scope to start looking in
|
||||
* @param type token containing variable type
|
||||
* @return pointer to type if found or NULL if not found
|
||||
*/
|
||||
const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const;
|
||||
|
||||
private:
|
||||
void addFunction(SpaceInfo **info, const Token **tok, const Token *argStart);
|
||||
void addNewFunction(SpaceInfo **info, const Token **tok);
|
||||
|
@ -253,8 +263,6 @@ private:
|
|||
bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const;
|
||||
bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
||||
|
||||
const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const;
|
||||
|
||||
const Tokenizer *_tokenizer;
|
||||
const Settings *_settings;
|
||||
ErrorLogger *_errorLogger;
|
||||
|
|
|
@ -79,6 +79,7 @@ private:
|
|||
TEST_CASE(localvar29); // ticket #2206 (array initialization)
|
||||
TEST_CASE(localvar30);
|
||||
TEST_CASE(localvar31); // ticket #2286
|
||||
TEST_CASE(localvar32); // ticket #2330
|
||||
TEST_CASE(localvaralias1);
|
||||
TEST_CASE(localvaralias2); // ticket #1637
|
||||
TEST_CASE(localvaralias3); // ticket #1639
|
||||
|
@ -1334,6 +1335,16 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void localvar32() // ticket #2330
|
||||
{
|
||||
functionVariableUsage("void f() {\n"
|
||||
" int x;\n"
|
||||
" fstream &f = getfile();\n"
|
||||
" f >> x;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void localvaralias1()
|
||||
{
|
||||
|
@ -2556,6 +2567,24 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("struct Fred { int a; };\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
" Fred* fred = new Fred;\n"
|
||||
" std::cout << \"test\" << std::endl;\n"
|
||||
" delete fred;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'fred' is allocated memory that is never used\n", errout.str());
|
||||
|
||||
functionVariableUsage("struct Fred { int a; Fred() : a(0) {} };\n"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
" Fred* fred = new Fred;\n"
|
||||
" std::cout << \"test\" << std::endl;\n"
|
||||
" delete fred;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("void foo()\n"
|
||||
"{\n"
|
||||
" Fred* fred = malloc(sizeof(Fred));\n"
|
||||
|
|
Loading…
Reference in New Issue