diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 709c6f9f5..334c4ecd3 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -181,46 +181,18 @@ void CheckString::checkSuspiciousStringCompare() else if (!Token::Match(litTok, "%char%|%num%|%str%")) continue; - if (mTokenizer->isCPP() && (!varTok->valueType() || !varTok->valueType()->isIntegral())) + if (varTok->isLiteral()) continue; - // Pointer addition? - if (varTok->str() == "+" && mTokenizer->isC()) { - const Token * const tokens[2] = { varTok->astOperand1(), varTok->astOperand2() }; - for (const Token * t : tokens) { - while (t && (t->str() == "." || t->str() == "::")) - t = t->astOperand2(); - if (t && t->variable() && t->variable()->isPointer()) - varTok = t; - } - } - - const Token* oldVarTok = varTok; - while (varTok->str() == "*") { - if (!mTokenizer->isC() || varTok->astOperand2() != nullptr || litTok->tokType() != Token::eString) - break; - varTok = varTok->astOperand1(); - } - - if (mTokenizer->isC() && varTok->str() == "&") - varTok = varTok->astOperand1(); - - if (varTok->str() == "[") - varTok = varTok->astOperand1(); - - while (varTok && (varTok->str() == "." || varTok->str() == "::")) - varTok = varTok->astOperand2(); - if (!varTok || !varTok->isName()) + const ValueType* varType = varTok->valueType(); + if (mTokenizer->isCPP() && (!varType || !varType->isIntegral())) continue; - const Variable *var = varTok->variable(); - - const bool ischar(litTok->tokType() == Token::eChar); if (litTok->tokType() == Token::eString) { - if (mTokenizer->isC() || (var && var->isArrayOrPointer())) - suspiciousStringCompareError(tok, oldVarTok->expressionString(), litTok->isLong()); - } else if (ischar && var && var->isPointer()) { - suspiciousStringCompareError_char(tok, oldVarTok->expressionString()); + if (mTokenizer->isC() || (varType && varType->pointer)) + suspiciousStringCompareError(tok, varTok->expressionString(), litTok->isLong()); + } else if (litTok->tokType() == Token::eChar && varType && varType->pointer) { + suspiciousStringCompareError_char(tok, varTok->expressionString()); } } } diff --git a/test/teststring.cpp b/test/teststring.cpp index 17a3d457a..f4bef1bcf 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -317,7 +317,7 @@ private: check("bool foo(char* c) {\n" " return \"x\" == c+foo;\n" "}", "test.c"); - ASSERT_EQUALS("[test.c:2]: (warning) String literal compared with variable 'c'. Did you intend to use strcmp() instead?\n", errout.str()); + ASSERT_EQUALS("[test.c:2]: (warning) String literal compared with variable 'c+foo'. Did you intend to use strcmp() instead?\n", errout.str()); check("bool foo(Foo c) {\n" " return \"x\" == c.foo;\n" @@ -424,6 +424,21 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + check("bool foo(char* c) {\n" + " return c[0] == '\\0';\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("bool foo(char** c) {\n" + " return c[0] == '\\0';\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (warning) Char literal compared with pointer 'c[0]'. Did you intend to dereference it?\n", errout.str()); + + check("bool foo(char** c) {\n" + " return *c == '\\0';\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (warning) Char literal compared with pointer '*c'. Did you intend to dereference it?\n", errout.str()); + check("bool foo(char c) {\n" " return c == 0;\n" "}");