Cache option flags and check them first.

This commit is contained in:
Dmitry-Me 2014-07-23 17:06:27 +04:00
parent 2e60f30bfc
commit 07c120f1af
3 changed files with 27 additions and 22 deletions

View File

@ -338,7 +338,9 @@ void CheckIO::seekOnAppendedFileError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckIO::invalidScanf() void CheckIO::invalidScanf()
{ {
if (!_settings->isEnabled("warning") && !_settings->isEnabled("portability")) const bool warning = _settings->isEnabled("warning");
const bool portability = _settings->isEnabled("portability");
if (!warning && !portability)
return; return;
const bool windows = _settings->isWindowsPlatform(); const bool windows = _settings->isWindowsPlatform();
@ -375,9 +377,9 @@ void CheckIO::invalidScanf()
} }
else if (std::isalpha((unsigned char)formatstr[i]) || formatstr[i] == '[') { else if (std::isalpha((unsigned char)formatstr[i]) || formatstr[i] == '[') {
if ((formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's')) && _settings->isEnabled("warning")) // #3490 - field width limits are only necessary for string input if (warning && (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's'))) // #3490 - field width limits are only necessary for string input
invalidScanfError(tok, false); invalidScanfError(tok, false);
else if (formatstr[i] != 'n' && formatstr[i] != 'c' && !windows && _settings->isEnabled("portability")) else if (portability && formatstr[i] != 'n' && formatstr[i] != 'c' && !windows)
invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25 invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25
format = false; format = false;
} }
@ -1322,10 +1324,12 @@ void CheckIO::checkWrongPrintfScanfArguments()
argListTok2 = argListTok2->nextArgument(); // Find next argument argListTok2 = argListTok2->nextArgument(); // Find next argument
} }
// Check that all parameter positions reference an actual parameter if (warning) {
for (std::set<unsigned int>::const_iterator it = parameterPositionsUsed.begin() ; it != parameterPositionsUsed.end() ; ++it) { // Check that all parameter positions reference an actual parameter
if (((*it == 0) || (*it > numFormat)) && _settings->isEnabled("warning")) for (std::set<unsigned int>::const_iterator it = parameterPositionsUsed.begin() ; it != parameterPositionsUsed.end() ; ++it) {
wrongPrintfScanfPosixParameterPositionError(tok, tok->str(), *it, numFormat); if ((*it == 0) || (*it > numFormat))
wrongPrintfScanfPosixParameterPositionError(tok, tok->str(), *it, numFormat);
}
} }
// Mismatching number of parameters => warning // Mismatching number of parameters => warning

View File

@ -798,7 +798,7 @@ void CheckOther::checkRedundantAssignment()
memAssignments[param1->varId()] = tok; memAssignments[param1->varId()] = tok;
else { else {
const std::map<unsigned int, const Token*>::iterator it = memAssignments.find(param1->varId()); const std::map<unsigned int, const Token*>::iterator it = memAssignments.find(param1->varId());
if (scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok) && warning) if (warning && scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok))
redundantCopyInSwitchError(it->second, tok, param1->str()); redundantCopyInSwitchError(it->second, tok, param1->str());
else if (performance) else if (performance)
redundantCopyError(it->second, tok, param1->str()); redundantCopyError(it->second, tok, param1->str());

View File

@ -763,8 +763,8 @@ static bool if_findCompare(const Token * const tokBack, bool str)
void CheckStl::if_find() void CheckStl::if_find()
{ {
bool warning = _settings->isEnabled("warning"); const bool warning = _settings->isEnabled("warning");
bool performance = _settings->isEnabled("performance"); const bool performance = _settings->isEnabled("performance");
if (!warning && !performance) if (!warning && !performance)
return; return;
@ -1093,6 +1093,7 @@ static bool isLocal(const Token *tok)
void CheckStl::string_c_str() void CheckStl::string_c_str()
{ {
const bool performance = _settings->isEnabled("performance");
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY // THIS ARRAY MUST BE ORDERED ALPHABETICALLY
static const char* const stl_string[] = { static const char* const stl_string[] = {
"string", "u16string", "u32string", "wstring" "string", "u16string", "u32string", "wstring"
@ -1106,7 +1107,7 @@ void CheckStl::string_c_str()
// Find all functions that take std::string as argument // Find all functions that take std::string as argument
std::multimap<std::string, unsigned int> c_strFuncParam; std::multimap<std::string, unsigned int> c_strFuncParam;
if (_settings->isEnabled("performance")) { if (performance) {
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
if (c_strFuncParam.erase(func->tokenDef->str()) != 0) { // Check if function with this name was already found if (c_strFuncParam.erase(func->tokenDef->str()) != 0) { // Check if function with this name was already found
@ -1154,8 +1155,8 @@ void CheckStl::string_c_str()
const Variable* var = tok->next()->variable(); const Variable* var = tok->next()->variable();
if (var && var->isPointer()) if (var && var->isPointer())
string_c_strError(tok); string_c_strError(tok);
} else if (Token::Match(tok, "%var% ( !!)") && c_strFuncParam.find(tok->str()) != c_strFuncParam.end() && } else if (performance && Token::Match(tok, "%var% ( !!)") && c_strFuncParam.find(tok->str()) != c_strFuncParam.end() &&
_settings->isEnabled("performance") && !Token::Match(tok->previous(), "::|.") && tok->varId() == 0 && tok->str() != scope->className) { // calling function. TODO: Add support for member functions !Token::Match(tok->previous(), "::|.") && tok->varId() == 0 && tok->str() != scope->className) { // calling function. TODO: Add support for member functions
std::pair<std::multimap<std::string, unsigned int>::const_iterator, std::multimap<std::string, unsigned int>::const_iterator> range = c_strFuncParam.equal_range(tok->str()); std::pair<std::multimap<std::string, unsigned int>::const_iterator, std::multimap<std::string, unsigned int>::const_iterator> range = c_strFuncParam.equal_range(tok->str());
for (std::multimap<std::string, unsigned int>::const_iterator i = range.first; i != range.second; ++i) { for (std::multimap<std::string, unsigned int>::const_iterator i = range.first; i != range.second; ++i) {
if (i->second == 0) if (i->second == 0)
@ -1223,7 +1224,7 @@ void CheckStl::string_c_str()
} }
} }
// Using c_str() to get the return value is redundant if the function returns std::string or const std::string&. // Using c_str() to get the return value is redundant if the function returns std::string or const std::string&.
else if ((returnType == stdString || returnType == stdStringConstRef) && _settings->isEnabled("performance")) { else if (performance && (returnType == stdString || returnType == stdStringConstRef)) {
if (tok->str() == "return") { if (tok->str() == "return") {
const Token* tok2 = Token::findsimplematch(tok->next(), ";"); const Token* tok2 = Token::findsimplematch(tok->next(), ";");
if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) {
@ -1375,8 +1376,8 @@ void CheckStl::uselessCalls()
"unordered_set", "vector", "wstring" "unordered_set", "vector", "wstring"
}; };
bool performance = _settings->isEnabled("performance"); const bool performance = _settings->isEnabled("performance");
bool warning = _settings->isEnabled("warning"); const bool warning = _settings->isEnabled("warning");
if (!performance && !warning) if (!performance && !warning)
return; return;
@ -1385,13 +1386,13 @@ void CheckStl::uselessCalls()
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) { for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (tok->varId() && Token::Match(tok, "%var% . compare|find|rfind|find_first_not_of|find_first_of|find_last_not_of|find_last_of ( %var% [,)]") && if (warning && tok->varId() && Token::Match(tok, "%var% . compare|find|rfind|find_first_not_of|find_first_of|find_last_not_of|find_last_of ( %var% [,)]") &&
tok->varId() == tok->tokAt(4)->varId() && warning) { tok->varId() == tok->tokAt(4)->varId()) {
uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2)); uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2));
} else if (tok->varId() && Token::Match(tok, "%var% . swap ( %var% )") && } else if (performance && tok->varId() && Token::Match(tok, "%var% . swap ( %var% )") &&
tok->varId() == tok->tokAt(4)->varId() && performance) { tok->varId() == tok->tokAt(4)->varId()) {
uselessCallsSwapError(tok, tok->str()); uselessCallsSwapError(tok, tok->str());
} else if (Token::Match(tok, "%var% . substr (") && performance && } else if (performance && Token::Match(tok, "%var% . substr (") &&
tok->variable() && tok->variable()->isStlType(stl_string)) { tok->variable() && tok->variable()->isStlType(stl_string)) {
if (Token::Match(tok->tokAt(4), "0| )")) if (Token::Match(tok->tokAt(4), "0| )"))
uselessCallsSubstrError(tok, false); uselessCallsSubstrError(tok, false);
@ -1400,7 +1401,7 @@ void CheckStl::uselessCalls()
uselessCallsSubstrError(tok, false); uselessCallsSubstrError(tok, false);
} else if (Token::simpleMatch(tok->linkAt(3)->tokAt(-2), ", 0 )")) } else if (Token::simpleMatch(tok->linkAt(3)->tokAt(-2), ", 0 )"))
uselessCallsSubstrError(tok, true); uselessCallsSubstrError(tok, true);
} else if (Token::Match(tok, "[{};] %var% . empty ( ) ;") && warning && } else if (warning && Token::Match(tok, "[{};] %var% . empty ( ) ;") &&
tok->next()->variable() && tok->next()->variable()->isStlType(stl_containers_with_empty_and_clear)) tok->next()->variable() && tok->next()->variable()->isStlType(stl_containers_with_empty_and_clear))
uselessCallsEmptyError(tok->next()); uselessCallsEmptyError(tok->next());
else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument()) else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument())