Check for useless calls of .empty() (#3816)

Messages from CheckStl::uselessCalls() only shown when correct severity is enabled.
This commit is contained in:
PKEuS 2012-07-12 03:23:52 -07:00
parent 3523f89917
commit 5a91d6a0f5
3 changed files with 24 additions and 6 deletions

View File

@ -1247,7 +1247,7 @@ void CheckStl::checkAutoPointer()
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "auto_ptr <")) {
if ((tok->previous() && tok->previous()->str() == "<" && Token::Match(tok->tokAt(-2), STL_CONTAINER_LIST)) ||
if ((tok->strAt(-1) == "<" && Token::Match(tok->tokAt(-2), STL_CONTAINER_LIST)) ||
(Token::simpleMatch(tok->tokAt(-3), "< std :: auto_ptr") && Token::Match(tok->tokAt(-4), STL_CONTAINER_LIST))) {
autoPointerContainerError(tok);
} else {
@ -1327,21 +1327,27 @@ void CheckStl::autoPointerArrayError(const Token *tok)
void CheckStl::uselessCalls()
{
bool performance = _settings->isEnabled("performance");
bool style = _settings->isEnabled("style");
if (!performance && !style)
return;
for (const Token *tok = _tokenizer->tokens(); tok; 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% [,)]") &&
tok->varId() == tok->tokAt(4)->varId()) {
tok->varId() == tok->tokAt(4)->varId() && style) {
uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2));
} else if (tok->varId() && Token::Match(tok, "%var% . swap ( %var% )") &&
tok->varId() == tok->tokAt(4)->varId()) {
tok->varId() == tok->tokAt(4)->varId() && performance) {
uselessCallsSwapError(tok, tok->str());
} else if (Token::simpleMatch(tok, ". substr (")) {
} else if (Token::simpleMatch(tok, ". substr (") && performance) {
if (Token::Match(tok->tokAt(3), "0| )"))
uselessCallsSubstrError(tok, false);
else if (tok->strAt(3) == "0" && tok->linkAt(2)->strAt(-1) == "npos")
uselessCallsSubstrError(tok, false);
else if (Token::simpleMatch(tok->linkAt(2)->tokAt(-2), ", 0 )"))
uselessCallsSubstrError(tok, true);
}
} else if (Token::Match(tok, "[{}:;] %var% . empty ( ) ;") && style)
uselessCallsEmptyError(tok);
}
}
@ -1374,3 +1380,8 @@ void CheckStl::uselessCallsSubstrError(const Token *tok, bool empty)
else
reportError(tok, Severity::performance, "uselessCallsSubstr", "Useless call of function 'substr' because it returns a copy of the object. Use operator= instead.");
}
void CheckStl::uselessCallsEmptyError(const Token *tok)
{
reportError(tok, Severity::warning, "uselessCallsEmpty", "Useless call of function 'empty()'. Did you intend to call 'clear()' instead?");
}

View File

@ -175,6 +175,7 @@ private:
void uselessCallsReturnValueError(const Token *tok, const std::string &varname, const std::string &function);
void uselessCallsSwapError(const Token *tok, const std::string &varname);
void uselessCallsSubstrError(const Token *tok, bool empty);
void uselessCallsEmptyError(const Token *tok);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
CheckStl c(0, settings, errorLogger);
@ -200,6 +201,7 @@ private:
c.uselessCallsReturnValueError(0, "str", "find");
c.uselessCallsSwapError(0, "str");
c.uselessCallsSubstrError(0, false);
c.uselessCallsEmptyError(0);
}
std::string myName() const {
@ -218,7 +220,7 @@ private:
"* redundant condition\n"
"* common mistakes when using string::c_str()\n"
"* using auto pointer (auto_ptr)\n"
"* useless calls of string functions";
"* useless calls of string and STL functions";
}
bool isStlContainer(unsigned int varid);

View File

@ -1864,6 +1864,11 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
check("bool foo(std::vector<int>& v) {\n"
" v.empty();\n"
" return v.empty();\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Useless call of function 'empty()'. Did you intend to call 'clear()' instead?\n", errout.str());
}
};