Refactorized CheckObsoleteFunctions:
- Speedup checkobsoletefunctions by using symboldatabase and by not calling SymbolDatabase::findFunctionByToken() for each function call. -> Benchmark (SQlite amalgamation): CheckObsoleteFunctions::runSimplifiedChecks(): 9s -> 0,016s (562%, 4% on entire runtime) - Fixed false negative when passing function result as parameter
This commit is contained in:
parent
578e582987
commit
410c0f98d9
|
@ -38,42 +38,38 @@ void CheckObsoleteFunctions::obsoleteFunctions()
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
// Functions defined somewhere?
|
||||||
|
for (unsigned int i = 0; i < symbolDatabase->functionScopes.size(); i++) {
|
||||||
|
const Scope* scope = symbolDatabase->functionScopes[i];
|
||||||
|
_obsoleteStandardFunctions.erase(scope->className);
|
||||||
|
_obsoletePosixFunctions.erase(scope->className);
|
||||||
|
_obsoleteC99Functions.erase(scope->className);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < symbolDatabase->functionScopes.size(); i++) {
|
||||||
|
const Scope* scope = symbolDatabase->functionScopes[i];
|
||||||
|
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
|
||||||
if (tok->isName() && tok->varId()==0 && (tok->next() && tok->next()->str() == "(") &&
|
if (tok->isName() && tok->varId()==0 && (tok->next() && tok->next()->str() == "(") &&
|
||||||
(!Token::Match(tok->previous(), ".|::|:|,") || Token::simpleMatch(tok->tokAt(-2), "std :: gets"))) {
|
(!Token::Match(tok->previous(), ".|::") || Token::simpleMatch(tok->tokAt(-2), "std ::"))) {
|
||||||
// c function declaration?
|
|
||||||
if ((tok->next()->link()->next() && tok->next()->link()->next()->str() == ";") && (tok->previous() && (tok->previous()->str() == "*" || tok->previous()->isName()))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function declaration?
|
|
||||||
const Function * function = symbolDatabase->findFunctionByToken(tok);
|
|
||||||
if (function && function->hasBody) {
|
|
||||||
_obsoleteStandardFunctions.erase(tok->str());
|
|
||||||
_obsoletePosixFunctions.erase(tok->str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string,std::string>::const_iterator it = _obsoleteStandardFunctions.find(tok->str());
|
std::map<std::string,std::string>::const_iterator it = _obsoleteStandardFunctions.find(tok->str());
|
||||||
if (it != _obsoleteStandardFunctions.end()) {
|
if (it != _obsoleteStandardFunctions.end()) {
|
||||||
// If checking an old code base it might be uninteresting to update obsolete functions.
|
// If checking an old code base it might be uninteresting to update obsolete functions.
|
||||||
// Therefore this is "information"
|
reportError(tok, Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
reportError(tok->next(), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
|
||||||
} else {
|
} else {
|
||||||
if (_settings->standards.posix) {
|
if (_settings->standards.posix) {
|
||||||
it = _obsoletePosixFunctions.find(tok->str());
|
it = _obsoletePosixFunctions.find(tok->str());
|
||||||
if (it != _obsoletePosixFunctions.end()) {
|
if (it != _obsoletePosixFunctions.end()) {
|
||||||
// If checking an old code base it might be uninteresting to update obsolete functions.
|
// If checking an old code base it might be uninteresting to update obsolete functions.
|
||||||
// Therefore this is "information"
|
reportError(tok, Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
reportError(tok->next(), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_settings->standards.c >= Standards::C99) {
|
if (_settings->standards.c >= Standards::C99) {
|
||||||
// alloca : this function is obsolete in C but not in C++ (#4382)
|
// alloca : this function is obsolete in C but not in C++ (#4382)
|
||||||
it = _obsoleteC99Functions.find(tok->str());
|
it = _obsoleteC99Functions.find(tok->str());
|
||||||
if (it != _obsoleteC99Functions.end() && !(tok->str() == "alloca" && _tokenizer->isCPP())) {
|
if (it != _obsoleteC99Functions.end() && !(tok->str() == "alloca" && _tokenizer->isCPP())) {
|
||||||
reportError(tok->next(), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
reportError(tok, Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,12 @@ private:
|
||||||
" char *x = gets();\n"
|
" char *x = gets();\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" foo(x, gets());\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void testalloca() {
|
void testalloca() {
|
||||||
|
|
Loading…
Reference in New Issue