Fixed more false negatives (and recently introduced false positives) literalWithCharPtrCompare by using ValueType
Merged from LCppC.
This commit is contained in:
parent
b1ccad5f02
commit
29a6031cea
|
@ -181,46 +181,18 @@ void CheckString::checkSuspiciousStringCompare()
|
||||||
else if (!Token::Match(litTok, "%char%|%num%|%str%"))
|
else if (!Token::Match(litTok, "%char%|%num%|%str%"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mTokenizer->isCPP() && (!varTok->valueType() || !varTok->valueType()->isIntegral()))
|
if (varTok->isLiteral())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Pointer addition?
|
const ValueType* varType = varTok->valueType();
|
||||||
if (varTok->str() == "+" && mTokenizer->isC()) {
|
if (mTokenizer->isCPP() && (!varType || !varType->isIntegral()))
|
||||||
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())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Variable *var = varTok->variable();
|
|
||||||
|
|
||||||
const bool ischar(litTok->tokType() == Token::eChar);
|
|
||||||
if (litTok->tokType() == Token::eString) {
|
if (litTok->tokType() == Token::eString) {
|
||||||
if (mTokenizer->isC() || (var && var->isArrayOrPointer()))
|
if (mTokenizer->isC() || (varType && varType->pointer))
|
||||||
suspiciousStringCompareError(tok, oldVarTok->expressionString(), litTok->isLong());
|
suspiciousStringCompareError(tok, varTok->expressionString(), litTok->isLong());
|
||||||
} else if (ischar && var && var->isPointer()) {
|
} else if (litTok->tokType() == Token::eChar && varType && varType->pointer) {
|
||||||
suspiciousStringCompareError_char(tok, oldVarTok->expressionString());
|
suspiciousStringCompareError_char(tok, varTok->expressionString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ private:
|
||||||
check("bool foo(char* c) {\n"
|
check("bool foo(char* c) {\n"
|
||||||
" return \"x\" == c+foo;\n"
|
" return \"x\" == c+foo;\n"
|
||||||
"}", "test.c");
|
"}", "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"
|
check("bool foo(Foo c) {\n"
|
||||||
" return \"x\" == c.foo;\n"
|
" return \"x\" == c.foo;\n"
|
||||||
|
@ -424,6 +424,21 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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"
|
check("bool foo(char c) {\n"
|
||||||
" return c == 0;\n"
|
" return c == 0;\n"
|
||||||
"}");
|
"}");
|
||||||
|
|
Loading…
Reference in New Issue