Symbol database: more function/variable cleanup. Ticket: #4494
This commit is contained in:
parent
fc42aa3a30
commit
ec1c86c152
|
@ -230,7 +230,7 @@ bool CheckAutoVariables::returnTemporary(const Token *tok) const
|
||||||
bool retref = false; // is there such a function that returns a reference?
|
bool retref = false; // is there such a function that returns a reference?
|
||||||
bool retvalue = false; // is there such a function that returns a value?
|
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) {
|
if (function) {
|
||||||
retref = function->tokenDef->strAt(-1) == "&";
|
retref = function->tokenDef->strAt(-1) == "&";
|
||||||
if (!retref) {
|
if (!retref) {
|
||||||
|
|
|
@ -625,7 +625,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
|
||||||
// Calling a user function?
|
// Calling a user function?
|
||||||
// only 1-dimensional arrays can be checked currently
|
// only 1-dimensional arrays can be checked currently
|
||||||
else if (arrayInfo.num().size() == 1) {
|
else if (arrayInfo.num().size() == 1) {
|
||||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(&tok);
|
const Function* func = tok.function();
|
||||||
|
|
||||||
if (func && func->hasBody) {
|
if (func && func->hasBody) {
|
||||||
// Get corresponding parameter..
|
// Get corresponding parameter..
|
||||||
|
@ -695,7 +695,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p
|
||||||
|
|
||||||
// Check 'float x[10]' arguments in declaration
|
// Check 'float x[10]' arguments in declaration
|
||||||
if (_settings->isEnabled("style")) {
|
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 argument is '%type% a[num]' then check bounds against num
|
||||||
if (func) {
|
if (func) {
|
||||||
|
|
|
@ -219,7 +219,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
||||||
tok2 = tok2->tokAt(2);
|
tok2 = tok2->tokAt(2);
|
||||||
|
|
||||||
// User function
|
// User function
|
||||||
const Function* func = tokenizer->getSymbolDatabase()->findFunction(tok2);
|
const Function* func = tok2->function();
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return No;
|
return No;
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
||||||
|
|
||||||
// lock/unlock..
|
// lock/unlock..
|
||||||
if (varid == 0) {
|
if (varid == 0) {
|
||||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
|
const Function* func = tok->function();
|
||||||
if (!func || !func->hasBody)
|
if (!func || !func->hasBody)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -689,7 +689,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
||||||
if (dot)
|
if (dot)
|
||||||
return "use";
|
return "use";
|
||||||
|
|
||||||
const Function* function = _tokenizer->getSymbolDatabase()->findFunction(functok);
|
const Function* function = functok->function();
|
||||||
if (!function)
|
if (!function)
|
||||||
return "use";
|
return "use";
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (varid > 0 && Token::Match(tok, "& %varid% [,()]", varid)) {
|
if (varid > 0 && Token::Match(tok, "& %varid% [,()]", varid)) {
|
||||||
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(functok);
|
const Function *func = functok->function();
|
||||||
if (func == 0)
|
if (func == 0)
|
||||||
continue;
|
continue;
|
||||||
AllocType a;
|
AllocType a;
|
||||||
|
|
|
@ -450,7 +450,7 @@ bool CheckNullPointer::CanFunctionAssignPointer(const Token *functiontoken, unsi
|
||||||
unsigned int argumentNumber = 0;
|
unsigned int argumentNumber = 0;
|
||||||
for (const Token *arg = functiontoken->tokAt(2); arg; arg = arg->nextArgument()) {
|
for (const Token *arg = functiontoken->tokAt(2); arg; arg = arg->nextArgument()) {
|
||||||
if (Token::Match(arg, "%varid% [,)]", varid)) {
|
if (Token::Match(arg, "%varid% [,)]", varid)) {
|
||||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(functiontoken);
|
const Function* func = functiontoken->function();
|
||||||
if (!func) { // Unknown function
|
if (!func) { // Unknown function
|
||||||
unknown = true;
|
unknown = true;
|
||||||
return true; // assume that the function might assign the pointer
|
return true; // assume that the function might assign the pointer
|
||||||
|
|
|
@ -753,7 +753,7 @@ void CheckOther::checkRedundantAssignment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (scope->type == Scope::eSwitch) { // Avoid false positives if noreturn function is called in switch
|
} 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) {
|
if (!func || !func->hasBody) {
|
||||||
varAssignments.clear();
|
varAssignments.clear();
|
||||||
memAssignments.clear();
|
memAssignments.clear();
|
||||||
|
@ -2379,7 +2379,7 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
if (Token::Match(tok, "[;{}] %var% (")
|
if (Token::Match(tok, "[;{}] %var% (")
|
||||||
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
||||||
&& symbolDatabase->isClassOrStruct(tok->next()->str())
|
&& symbolDatabase->isClassOrStruct(tok->next()->str())
|
||||||
&& !symbolDatabase->findFunction(tok->next())) {
|
&& !tok->next()->function()) {
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
misusedScopeObjectError(tok, tok->str());
|
misusedScopeObjectError(tok, tok->str());
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
@ -2422,7 +2422,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
|
||||||
first_token = tok->previous();
|
first_token = tok->previous();
|
||||||
}
|
}
|
||||||
if (Token::Match(first_token, "%var% (") && !Token::Match(first_token->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") {
|
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
|
||||||
first_token_func_of_type_bool = true;
|
first_token_func_of_type_bool = true;
|
||||||
}
|
}
|
||||||
|
@ -2434,7 +2434,7 @@ void CheckOther::checkComparisonOfFuncReturningBool()
|
||||||
second_token = second_token->next();
|
second_token = second_token->next();
|
||||||
}
|
}
|
||||||
if (Token::Match(second_token, "%var% (") && !Token::Match(second_token->previous(), "::|.")) {
|
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") {
|
if (func && func->tokenDef && func->tokenDef->strAt(-1) == "bool") {
|
||||||
second_token_func_of_type_bool = true;
|
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;
|
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"
|
if (match_end==NULL || !Token::Match(match_end,expect_end_token)) //avoid usage like "const A a = getA()+3"
|
||||||
break;
|
break;
|
||||||
const Function* func = _tokenizer->getSymbolDatabase()->findFunction(tok);
|
const Function* func = tok->function();
|
||||||
if (func && func->tokenDef->previous() && func->tokenDef->previous()->str() == "&") {
|
if (func && func->tokenDef->previous() && func->tokenDef->previous()->str() == "&") {
|
||||||
redundantCopyError(var_tok,var_tok->str());
|
redundantCopyError(var_tok,var_tok->str());
|
||||||
}
|
}
|
||||||
|
@ -3842,7 +3842,7 @@ void CheckOther::checkVarFuncNullUB()
|
||||||
ftok = ftok ? ftok->previous() : NULL;
|
ftok = ftok ? ftok->previous() : NULL;
|
||||||
if (ftok && ftok->isName()) {
|
if (ftok && ftok->isName()) {
|
||||||
// If this is a variadic function then report error
|
// 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) {
|
if (f && f->argCount() <= argnr) {
|
||||||
const Token *tok2 = f->argDef;
|
const Token *tok2 = f->argDef;
|
||||||
tok2 = tok2 ? tok2->link() : NULL; // goto ')'
|
tok2 = tok2 ? tok2->link() : NULL; // goto ')'
|
||||||
|
|
|
@ -1211,7 +1211,7 @@ void CheckStl::string_c_str()
|
||||||
Token::simpleMatch(tok->linkAt(4), ") . c_str ( ) ;")) {
|
Token::simpleMatch(tok->linkAt(4), ") . c_str ( ) ;")) {
|
||||||
string_c_strError(tok);
|
string_c_strError(tok);
|
||||||
} else if (Token::Match(tok, "return %var% (") && Token::simpleMatch(tok->linkAt(2), ") . c_str ( ) ;")) {
|
} 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"))
|
if (func && Token::Match(func->tokenDef->tokAt(-3), "std :: string|wstring"))
|
||||||
string_c_strError(tok);
|
string_c_strError(tok);
|
||||||
} else if (Token::simpleMatch(tok, "return (") &&
|
} else if (Token::simpleMatch(tok, "return (") &&
|
||||||
|
|
|
@ -1485,7 +1485,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const
|
||||||
// is this a function call?
|
// is this a function call?
|
||||||
if (start && Token::Match(start->previous(), "%var% (")) {
|
if (start && Token::Match(start->previous(), "%var% (")) {
|
||||||
// check how function handle uninitialized data arguments..
|
// check how function handle uninitialized data arguments..
|
||||||
const Function *func = _tokenizer->getSymbolDatabase()->findFunction(start->previous());
|
const Function *func = start->previous()->function();
|
||||||
if (func) {
|
if (func) {
|
||||||
const Variable *arg = func->getArgumentVar(argumentNumber);
|
const Variable *arg = func->getArgumentVar(argumentNumber);
|
||||||
if (arg) {
|
if (arg) {
|
||||||
|
|
|
@ -34,6 +34,8 @@ Token::Token(Token **t) :
|
||||||
_previous(0),
|
_previous(0),
|
||||||
_link(0),
|
_link(0),
|
||||||
_scope(0),
|
_scope(0),
|
||||||
|
_function(0),
|
||||||
|
_variable(0),
|
||||||
_str(""),
|
_str(""),
|
||||||
_varId(0),
|
_varId(0),
|
||||||
_fileIndex(0),
|
_fileIndex(0),
|
||||||
|
@ -198,6 +200,8 @@ void Token::deleteThis()
|
||||||
_linenr = _next->_linenr;
|
_linenr = _next->_linenr;
|
||||||
_link = _next->_link;
|
_link = _next->_link;
|
||||||
_scope = _next->_scope;
|
_scope = _next->_scope;
|
||||||
|
_function = _next->_function;
|
||||||
|
_variable = _next->_variable;
|
||||||
if (_link)
|
if (_link)
|
||||||
_link->link(this);
|
_link->link(this);
|
||||||
|
|
||||||
|
@ -217,6 +221,8 @@ void Token::deleteThis()
|
||||||
_linenr = _previous->_linenr;
|
_linenr = _previous->_linenr;
|
||||||
_link = _previous->_link;
|
_link = _previous->_link;
|
||||||
_scope = _previous->_scope;
|
_scope = _previous->_scope;
|
||||||
|
_function = _previous->_function;
|
||||||
|
_variable = _previous->_variable;
|
||||||
if (_link)
|
if (_link)
|
||||||
_link->link(this);
|
_link->link(this);
|
||||||
|
|
||||||
|
|
41
lib/token.h
41
lib/token.h
|
@ -25,6 +25,8 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
class Scope;
|
class Scope;
|
||||||
|
class Function;
|
||||||
|
class Variable;
|
||||||
|
|
||||||
/// @addtogroup Core
|
/// @addtogroup Core
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -439,17 +441,47 @@ public:
|
||||||
* Associate this token with given scope
|
* Associate this token with given scope
|
||||||
* @param s Scope to be associated
|
* @param s Scope to be associated
|
||||||
*/
|
*/
|
||||||
void scope(Scope* s) {
|
void scope(const Scope *s) {
|
||||||
_scope = s;
|
_scope = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to the scope containing this token.
|
* Returns a pointer to the scope containing this token.
|
||||||
*/
|
*/
|
||||||
Scope* scope() const {
|
const Scope *scope() const {
|
||||||
return _scope;
|
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.
|
* Links two elements against each other.
|
||||||
**/
|
**/
|
||||||
|
@ -541,7 +573,10 @@ private:
|
||||||
Token *_previous;
|
Token *_previous;
|
||||||
Token *_link;
|
Token *_link;
|
||||||
|
|
||||||
Scope* _scope;
|
// symbol database information
|
||||||
|
const Scope *_scope;
|
||||||
|
const Function *_function;
|
||||||
|
const Variable *_variable;
|
||||||
|
|
||||||
std::string _str;
|
std::string _str;
|
||||||
unsigned int _varId;
|
unsigned int _varId;
|
||||||
|
|
|
@ -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()
|
void Tokenizer::deleteSymbolDatabase()
|
||||||
{
|
{
|
||||||
// Clear scope pointers
|
// Clear scope, function, and variable pointers
|
||||||
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
|
for (Token* tok = list.front(); tok != list.back(); tok = tok->next()) {
|
||||||
tok->scope(0);
|
tok->scope(0);
|
||||||
|
tok->function(0);
|
||||||
|
tok->variable(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _symbolDatabase;
|
delete _symbolDatabase;
|
||||||
|
|
Loading…
Reference in New Issue