Improved check (#5553): Detect stricmp(var.c_str(), var.c_str())

This commit is contained in:
PKEuS 2014-03-17 17:41:45 +01:00
parent 5f67bc1b0a
commit fab6b56360
2 changed files with 41 additions and 31 deletions

View File

@ -2915,37 +2915,37 @@ void CheckOther::checkAlwaysTrueOrFalseStringCompare()
if (!_settings->isEnabled("warning"))
return;
const Token *tok = _tokenizer->tokens();
while (tok && (tok = Token::findmatch(tok, "strncmp|strcmp|stricmp|strcmpi|strcasecmp|wcscmp|wcsncmp ( %str% , %str% ")) != nullptr) {
const std::string &str1 = tok->strAt(2);
const std::string &str2 = tok->strAt(4);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(5);
}
tok = _tokenizer->tokens();
while (tok && (tok = Token::findmatch(tok, "QString :: compare ( %str% , %str% )")) != nullptr) {
const std::string &str1 = tok->strAt(4);
const std::string &str2 = tok->strAt(6);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(7);
}
tok = _tokenizer->tokens();
while (tok && (tok = Token::findmatch(tok, "strncmp|strcmp|stricmp|strcmpi|strcasecmp|wcscmp|wcsncmp ( %var% , %var% ")) != nullptr) {
const std::string &str1 = tok->strAt(2);
const std::string &str2 = tok->strAt(4);
if (str1 == str2)
alwaysTrueStringVariableCompareError(tok, str1, str2);
tok = tok->tokAt(5);
}
tok = _tokenizer->tokens();
while (tok && (tok = Token::findmatch(tok, "!!+ %str% ==|!= %str% !!+")) != nullptr) {
const std::string &str1 = tok->strAt(1);
const std::string &str2 = tok->strAt(3);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(5);
for (const Token* tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "strncmp|strcmp|stricmp|strcmpi|strcasecmp|wcscmp|wcsncmp (")) {
if (Token::Match(tok->tokAt(2), "%str% , %str% ")) {
const std::string &str1 = tok->strAt(2);
const std::string &str2 = tok->strAt(4);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(5);
} else if (Token::Match(tok->tokAt(2), "%var% , %var% ")) {
const std::string &str1 = tok->strAt(2);
const std::string &str2 = tok->strAt(4);
if (str1 == str2)
alwaysTrueStringVariableCompareError(tok, str1, str2);
tok = tok->tokAt(5);
} else if (Token::Match(tok->tokAt(2), "%var% . c_str ( ) , %var% . c_str ( ) ")) {
const std::string &str1 = tok->strAt(2);
const std::string &str2 = tok->strAt(8);
if (str1 == str2)
alwaysTrueStringVariableCompareError(tok, str1, str2);
tok = tok->tokAt(13);
}
} else if (Token::Match(tok, "QString :: compare ( %str% , %str% )")) {
const std::string &str1 = tok->strAt(4);
const std::string &str2 = tok->strAt(6);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(7);
} else if (Token::Match(tok, "!!+ %str% ==|!= %str% !!+")) {
const std::string &str1 = tok->strAt(1);
const std::string &str2 = tok->strAt(3);
alwaysTrueFalseStringCompareError(tok, str1, str2);
tok = tok->tokAt(5);
}
}
}

View File

@ -4982,6 +4982,16 @@ private:
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
check(
"int foo(const std::string& buf)\n"
"{\n"
" if (stricmp(buf.c_str(), buf.c_str()) == 0)"
" {"
" std::cout << \"Equal\n\""
" }"
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
check_preprocess_suppress(
"int main() {\n"
" if (\"str\" == \"str\") {\n"