From 90c7db15a018cbefcf8c733cee5aec6a9b32414e Mon Sep 17 00:00:00 2001 From: Richard Quirk Date: Fri, 28 Oct 2011 22:05:11 +0200 Subject: [PATCH] Add check for comparison of identical string variables --- lib/checkother.cpp | 19 +++++++++++++++++++ lib/checkother.h | 2 ++ test/testother.cpp | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 764a2ccaf..a5ebea7ee 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2257,6 +2257,7 @@ void CheckOther::checkAlwaysTrueOrFalseStringCompare() const char pattern1[] = "strncmp|strcmp|stricmp|strcmpi|strcasecmp|wcscmp ( %str% , %str% "; const char pattern2[] = "QString :: compare ( %str% , %str% )"; + const char pattern3[] = "strncmp|strcmp|stricmp|strcmpi|strcasecmp|wcscmp ( %var% , %var% "; const Token *tok = _tokenizer->tokens(); while (tok && (tok = Token::findmatch(tok, pattern1)) != NULL) { @@ -2269,6 +2270,14 @@ void CheckOther::checkAlwaysTrueOrFalseStringCompare() alwaysTrueFalseStringCompareError(tok, tok->strAt(4), tok->strAt(6)); tok = tok->tokAt(7); } + + tok = _tokenizer->tokens(); + while (tok && (tok = Token::findmatch(tok, pattern3)) != NULL) { + const Token *var1 = tok->tokAt(2); + const Token *var2 = tok->tokAt(4); + alwaysTrueStringVariableCompareError(tok, var1->str(), var2->str()); + tok = tok->tokAt(5); + } } void CheckOther::alwaysTrueFalseStringCompareError(const Token *tok, const std::string& str1, const std::string& str2) @@ -2291,6 +2300,16 @@ void CheckOther::alwaysTrueFalseStringCompareError(const Token *tok, const std:: } } +void CheckOther::alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2) +{ + if (str1 == str2) { + reportError(tok, Severity::warning, "stringCompare", + "Comparison of identical string variables.\n" + "The compared strings, '" + str1 + "' and '" + str2 + "', are identical. " + "This could be a logic bug."); + } +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CheckOther::sizeofsizeof() diff --git a/lib/checkother.h b/lib/checkother.h index 8dcd03133..60ec133e3 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -273,6 +273,7 @@ public: void duplicateBranchError(const Token *tok1, const Token *tok2); void duplicateExpressionError(const Token *tok1, const Token *tok2, const std::string &op); void alwaysTrueFalseStringCompareError(const Token *tok, const std::string& str1, const std::string& str2); + void alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2); void duplicateBreakError(const Token *tok); void assignBoolToPointerError(const Token *tok); void unsignedLessThanZeroError(const Token *tok, const std::string &varname); @@ -326,6 +327,7 @@ public: c.duplicateBranchError(0, 0); c.duplicateExpressionError(0, 0, "&&"); c.alwaysTrueFalseStringCompareError(0, "str1", "str2"); + c.alwaysTrueStringVariableCompareError(0, "varname1", "varname2"); c.duplicateBreakError(0); c.unsignedLessThanZeroError(0, "varname"); c.unsignedPositiveError(0, "varname"); diff --git a/test/testother.cpp b/test/testother.cpp index 5b18f3470..c27c2f003 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3428,6 +3428,16 @@ private: " }" "}"); ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of always identical static strings.\n", errout.str()); + + check_preprocess_suppress( + "int foo(const char *buf)\n" + "{\n" + " if (strcmp(buf, buf) == 0)" + " {" + " std::cout << \"Equal\n\"" + " }" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str()); } void check_signOfUnsignedVariable(const char code[]) {