Symbol database: more function/variable cleanup. Ticket: #4494

This commit is contained in:
Robert Reif 2013-01-31 06:41:18 +01:00 committed by Daniel Marjamäki
parent fc42aa3a30
commit ec1c86c152
10 changed files with 80 additions and 20 deletions

View File

@ -230,7 +230,7 @@ bool CheckAutoVariables::returnTemporary(const Token *tok) const
bool retref = false; // is there such a function that returns a reference?
bool retvalue = false; // is there such a function that returns a value?
const Function *function = symbolDatabase->findFunction(tok);
const Function *function = tok->function();
if (function) {
retref = function->tokenDef->strAt(-1) == "&";
if (!retref) {

View File

@ -625,7 +625,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
// Calling a user function?
// only 1-dimensional arrays can be checked currently
else if (arrayInfo.num().size() == 1) {
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(&tok);
const Function* func = tok.function();
if (func && func->hasBody) {
// Get corresponding parameter..
@ -695,7 +695,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
// Check 'float x[10]' arguments in declaration
if (_settings->isEnabled("style")) {
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(&tok);
const Function* func = tok.function();
// If argument is '%type% a[num]' then check bounds against num
if (func) {

View File

@ -219,7 +219,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
tok2 = tok2->tokAt(2);
// User function
const Function* func = tokenizer->getSymbolDatabase()->findFunction(tok2);
const Function* func = tok2->function();
if (func == NULL)
return No;
@ -643,7 +643,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
// lock/unlock..
if (varid == 0) {
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
const Function* func = tok->function();
if (!func || !func->hasBody)
return 0;
@ -689,7 +689,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
if (dot)
return "use";
const Function* function = _tokenizer->getSymbolDatabase()->findFunction(functok);
const Function* function = functok->function();
if (!function)
return "use";
@ -721,7 +721,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
return ret;
}
if (varid > 0 && Token::Match(tok, "& %varid% [,()]", varid)) {
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(functok);
const Function *func = functok->function();
if (func == 0)
continue;
AllocType a;

View File

@ -450,7 +450,7 @@ bool CheckNullPointer::CanFunctionAssignPointer(const Token *functiontoken, unsi
unsigned int argumentNumber = 0;
for (const Token *arg = functiontoken->tokAt(2); arg; arg = arg->nextArgument()) {
if (Token::Match(arg, "%varid% [,)]", varid)) {
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(functiontoken);
const Function* func = functiontoken->function();
if (!func) { // Unknown function
unknown = true;
return true; // assume that the function might assign the pointer

View File

@ -753,7 +753,7 @@ void CheckOther::checkRedundantAssignment()
}
}
} else if (scope->type == Scope::eSwitch) { // Avoid false positives if noreturn function is called in switch
const Function* func = symbolDatabase->findFunction(tok);
const Function* func = tok->function();
if (!func || !func->hasBody) {
varAssignments.clear();
memAssignments.clear();
@ -2379,7 +2379,7 @@ void CheckOther::checkMisusedScopedObject()
if (Token::Match(tok, "[;{}] %var% (")
&& Token::simpleMatch(tok->linkAt(2), ") ;")
&& symbolDatabase->isClassOrStruct(tok->next()->str())
&& !symbolDatabase->findFunction(tok->next())) {
&& !tok->next()->function()) {
tok = tok->next();
misusedScopeObjectError(tok, tok->str());
tok = tok->next();
@ -2422,7 +2422,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
first_token = tok->previous();
}
if (Token::Match(first_token, "%var% (") && !Token::Match(first_token->previous(), "::|.")) {
const Function* func = symbolDatabase->findFunction(first_token);
const Function* func = first_token->function();
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
first_token_func_of_type_bool = true;
}
@ -2434,7 +2434,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
second_token = second_token->next();
}
if (Token::Match(second_token, "%var% (") && !Token::Match(second_token->previous(), "::|.")) {
const Function* func = symbolDatabase->findFunction(second_token);
const Function* func = second_token->function();
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
second_token_func_of_type_bool = true;
}
@ -3657,7 +3657,7 @@ void CheckOther::checkRedundantCopy()
const Token *match_end = (tok->next()->link()!=NULL)?tok->next()->link()->next():NULL;
if (match_end==NULL || !Token::Match(match_end,expect_end_token)) //avoid usage like "const A a = getA()+3"
break;
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
const Function* func = tok->function();
if (func && func->tokenDef->previous() && func->tokenDef->previous()->str() == "&") {
redundantCopyError(var_tok,var_tok->str());
}
@ -3842,7 +3842,7 @@ void CheckOther::checkVarFuncNullUB()
ftok = ftok ? ftok->previous() : NULL;
if (ftok && ftok->isName()) {
// If this is a variadic function then report error
const Function *f = symbolDatabase->findFunction(ftok);
const Function *f = ftok->function();
if (f && f->argCount() <= argnr) {
const Token *tok2 = f->argDef;
tok2 = tok2 ? tok2->link() : NULL; // goto ')'

View File

@ -1211,7 +1211,7 @@ void CheckStl::string_c_str()
Token::simpleMatch(tok->linkAt(4), ") . c_str ( ) ;")) {
string_c_strError(tok);
} else if (Token::Match(tok, "return %var% (") && Token::simpleMatch(tok->linkAt(2), ") . c_str ( ) ;")) {
const Function* func =_tokenizer->getSymbolDatabase()->findFunction(tok->next());
const Function* func = tok->next()->function();
if (func && Token::Match(func->tokenDef->tokAt(-3), "std :: string|wstring"))
string_c_strError(tok);
} else if (Token::simpleMatch(tok, "return (") &&

View File

@ -1485,7 +1485,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const
// is this a function call?
if (start && Token::Match(start->previous(), "%var% (")) {
// check how function handle uninitialized data arguments..
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(start->previous());
const Function *func = start->previous()->function();
if (func) {
const Variable *arg = func->getArgumentVar(argumentNumber);
if (arg) {

View File

@ -34,6 +34,8 @@ Token::Token(Token **t) :
_previous(0),
_link(0),
_scope(0),
_function(0),
_variable(0),
_str(""),
_varId(0),
_fileIndex(0),
@ -198,6 +200,8 @@ void Token::deleteThis()
_linenr = _next->_linenr;
_link = _next->_link;
_scope = _next->_scope;
_function = _next->_function;
_variable = _next->_variable;
if (_link)
_link->link(this);
@ -217,6 +221,8 @@ void Token::deleteThis()
_linenr = _previous->_linenr;
_link = _previous->_link;
_scope = _previous->_scope;
_function = _previous->_function;
_variable = _previous->_variable;
if (_link)
_link->link(this);

View File

@ -25,6 +25,8 @@
#include "config.h"
class Scope;
class Function;
class Variable;
/// @addtogroup Core
/// @{
@ -439,17 +441,47 @@ public:
* Associate this token with given scope
* @param s Scope to be associated
*/
void scope(Scope* s) {
void scope(const Scope *s) {
_scope = s;
}
/**
* Returns a pointer to the scope containing this token.
*/
Scope* scope() const {
const Scope *scope() const {
return _scope;
}
/**
* Associate this token with given function
* @param f Function to be associated
*/
void function(const Function *f) {
_function = f;
}
/**
* Returns a pointer to the Function associated with this token.
*/
const Function *function() const {
return _function;
}
/**
* Associate this token with given variable
* @param v Variable to be associated
*/
void variable(const Variable *v) {
_variable = v;
}
/**
* Returns a pointer to the variable associated with this token.
*/
const Variable *variable() const {
return _variable;
}
/**
* Links two elements against each other.
**/
@ -541,7 +573,10 @@ private:
Token *_previous;
Token *_link;
Scope* _scope;
// symbol database information
const Scope *_scope;
const Function *_function;
const Variable *_variable;
std::string _str;
unsigned int _varId;

View File

@ -9264,14 +9264,33 @@ void Tokenizer::createSymbolDatabase()
}
}
}
// Set function pointers
const std::size_t functions = _symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = _symbolDatabase->functionScopes[i];
for (Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% (")) {
tok->function(_symbolDatabase->findFunction(tok));
}
}
}
// Set variable pointers
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
if (tok->varId())
tok->variable(_symbolDatabase->getVariableFromVarId(tok->varId()));
}
}
}
void Tokenizer::deleteSymbolDatabase()
{
// Clear scope pointers
// Clear scope, function, and variable pointers
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
tok->scope(0);
tok->function(0);
tok->variable(0);
}
delete _symbolDatabase;