convert last check in checkautovariables to use the symbol database

This commit is contained in:
Robert Reif 2011-04-23 09:50:56 -04:00
parent 40e644bec8
commit 55898c0dfc
3 changed files with 15 additions and 130 deletions

View File

@ -37,99 +37,34 @@ static CheckAutoVariables instance;
} }
// _callStack used when parsing into subfunctions.
bool CheckAutoVariables::errorAv(const Token* left, const Token* right) bool CheckAutoVariables::errorAv(const Token* left, const Token* right)
{ {
if (fp_list.find(left->str()) == fp_list.end()) const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(left->varId());
{
if (!var || !var->isArgument())
return false; return false;
}
return isAutoVar(right->varId()); return isAutoVar(right->varId());
} }
bool CheckAutoVariables::isAutoVar(unsigned int varId) bool CheckAutoVariables::isAutoVar(unsigned int varId)
{ {
if (varId == 0) const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
{
return false;
}
return (vd_list.find(varId) != vd_list.end()); if (!var || !var->isLocal() || var->isStatic() || var->isArray())
return false;
return true;
} }
bool CheckAutoVariables::isAutoVarArray(unsigned int varId) bool CheckAutoVariables::isAutoVarArray(unsigned int varId)
{ {
if (varId == 0) const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
{
if (!var || !var->isLocal() || var->isStatic() || !var->isArray())
return false; return false;
}
return (vda_list.find(varId) != vda_list.end()); return true;
}
void print(const Token *tok, int num)
{
const Token *t = tok;
std::cout << tok->linenr() << " PRINT ";
for (int i = 0; i < num; i++)
{
std::cout << " [" << t->str() << "] ";
t = t->next();
}
std::cout << std::endl;
}
bool isTypeName(const Token *tok)
{
bool ret = false;
const std::string _str(tok->str());
static const char * const type[] = {"case", "return", "delete", 0};
for (int i = 0; type[i]; i++)
{
ret |= (_str == type[i]);
}
return !ret;
}
bool isExternOrStatic(const Token *tok)
{
bool res = false;
if (Token::Match(tok->tokAt(-1), "extern|static"))
{
res = true;
}
else if (Token::Match(tok->tokAt(-2), "extern|static"))
{
res = true;
}
else if (Token::Match(tok->tokAt(-3), "extern|static"))
{
res = true;
}
//std::cout << __PRETTY_FUNCTION__ << " " << tok->str() << " " << res << std::endl;
return res;
}
void CheckAutoVariables::addVD(unsigned int varId)
{
if (varId > 0)
{
vd_list.insert(varId);
}
}
void CheckAutoVariables::addVDA(unsigned int varId)
{
if (varId > 0)
{
vda_list.insert(varId);
}
} }
void CheckAutoVariables::autoVariables() void CheckAutoVariables::autoVariables()
@ -144,28 +79,10 @@ void CheckAutoVariables::autoVariables()
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;
fp_list.clear();
vd_list.clear();
vda_list.clear();
const Token *tok = scope->classDef->next();
for (; tok && tok != scope->classDef->next()->link(); tok = tok->next())
{
if (Token::Match(tok, "%type% * * %var%"))
{
fp_list.insert(tok->tokAt(3)->str());
}
else if (Token::Match(tok, "%type% * %var% ["))
{
fp_list.insert(tok->tokAt(2)->str());
}
}
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
// Which variables have an unknown type? // Which variables have an unknown type?
std::set<unsigned int> unknown_type; std::set<unsigned int> unknown_type;
for (tok = scope->classDef->next()->link(); tok; tok = tok->next()) for (const Token *tok = scope->classDef->next()->link(); tok; tok = tok->next())
{ {
// indentlevel.. // indentlevel..
if (tok->str() == "{") if (tok->str() == "{")
@ -177,31 +94,8 @@ void CheckAutoVariables::autoVariables()
--indentlevel; --indentlevel;
} }
// Inside a function body
if (Token::Match(tok, "%type% :: %any%") && !isExternOrStatic(tok))
{
addVD(tok->tokAt(2)->varId());
}
else if (Token::Match(tok, "%type% %var% ["))
{
addVDA(tok->next()->varId());
}
else if (Token::Match(tok, "%var% %var% ;") && !isExternOrStatic(tok) && isTypeName(tok))
{
addVD(tok->next()->varId());
if (!tok->isStandardType() &&
!symbolDatabase->isClassOrStruct(tok->str()))
{
unknown_type.insert(tok->next()->varId());
}
}
else if (Token::Match(tok, "const %var% %var% ;") && !isExternOrStatic(tok) && isTypeName(tok->next()))
{
addVD(tok->tokAt(2)->varId());
}
//Critical assignment //Critical assignment
else if (Token::Match(tok, "[;{}] %var% = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(4))) if (Token::Match(tok, "[;{}] %var% = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(4)))
{ {
errorAutoVariableAssignment(tok); errorAutoVariableAssignment(tok);
} }
@ -225,10 +119,6 @@ void CheckAutoVariables::autoVariables()
reportError(tok, Severity::error, "autoVariables", "Invalid deallocation"); reportError(tok, Severity::error, "autoVariables", "Invalid deallocation");
} }
} }
vd_list.clear();
vda_list.clear();
fp_list.clear();
} }
} }

View File

@ -70,14 +70,9 @@ public:
void returncstr(); void returncstr();
private: private:
std::set<std::string> fp_list;
std::set<unsigned int> vd_list;
std::set<unsigned int> vda_list;
bool errorAv(const Token* left, const Token* right); bool errorAv(const Token* left, const Token* right);
bool isAutoVar(unsigned int varId); bool isAutoVar(unsigned int varId);
bool isAutoVarArray(unsigned int varId); bool isAutoVarArray(unsigned int varId);
void addVD(unsigned int varId);
void addVDA(unsigned int varId);
/** /**
* Returning a temporary object? * Returning a temporary object?

View File

@ -219,7 +219,7 @@ private:
" EventPtr event = *eventP;\n" " EventPtr event = *eventP;\n"
" *actionsP = &event->actions;\n" " *actionsP = &event->actions;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (error) Assigning address of local auto-variable to a function parameter.\n", errout.str());
} }
void returnLocalVariable1() void returnLocalVariable1()