Fixed false negatives literalWithCharPtrCompare when address-of operator (C only) or arrays are used, adapted TODO unit tests

Enabled working unit test in testunusedvar.cpp

Merged from LCppC.
This commit is contained in:
PKEuS 2021-02-20 12:42:48 +01:00 committed by Daniel Marjamäki
parent 3c6fae37e4
commit 423d7dbc3c
3 changed files with 22 additions and 19 deletions

View File

@ -195,12 +195,19 @@ void CheckString::checkSuspiciousStringCompare()
}
}
if (varTok->str() == "*") {
const Token* oldVarTok = varTok;
while (varTok->str() == "*") {
if (!mTokenizer->isC() || varTok->astOperand2() != nullptr || litTok->tokType() != Token::eString)
continue;
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())
@ -208,16 +215,12 @@ void CheckString::checkSuspiciousStringCompare()
const Variable *var = varTok->variable();
while (Token::Match(varTok->astParent(), "[.*]"))
varTok = varTok->astParent();
const std::string varname = varTok->expressionString();
const bool ischar(litTok->tokType() == Token::eChar);
if (litTok->tokType() == Token::eString) {
if (mTokenizer->isC() || (var && var->isArrayOrPointer()))
suspiciousStringCompareError(tok, varname, litTok->isLong());
suspiciousStringCompareError(tok, oldVarTok->expressionString(), litTok->isLong());
} else if (ischar && var && var->isPointer()) {
suspiciousStringCompareError_char(tok, varname);
suspiciousStringCompareError_char(tok, oldVarTok->expressionString());
}
}
}

View File

@ -289,6 +289,11 @@ private:
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) String literal compared with variable 'c'. Did you intend to use strcmp() instead?\n", errout.str());
check("bool foo(char** c) {\n"
" return c[3] == \"x\";\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) String literal compared with variable 'c[3]'. Did you intend to use strcmp() instead?\n", errout.str());
check("bool foo(wchar_t* c) {\n"
" return c == L\"x\";\n"
"}");
@ -349,18 +354,14 @@ private:
// Ticket #4257
check("bool foo() {\n"
"MyString **str=OtherGetter();\n"
"return *str==\"bug\"; }");
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) String literal compared with variable 'c'. Did you intend to use strcmp() instead?\n",
"",
errout.str());
"return *str==\"bug\"; }", "test.c");
ASSERT_EQUALS("[test.c:3]: (warning) String literal compared with variable '*str'. Did you intend to use strcmp() instead?\n", errout.str());
// Ticket #4257
check("bool foo() {\n"
"MyString str=OtherGetter2();\n"
"return &str==\"bug\"; }");
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) String literal compared with variable 'c'. Did you intend to use strcmp() instead?\n",
"",
errout.str());
"return &str==\"bug\"; }", "test.c");
ASSERT_EQUALS("[test.c:3]: (warning) String literal compared with variable '&str'. Did you intend to use strcmp() instead?\n", errout.str());
// Ticket #5734
check("int foo(char c) {\n"

View File

@ -5737,9 +5737,8 @@ private:
functionVariableUsage(
"void fun(std::string s) {\n"
" s[10] = 123;\n"
"}\n"
);
// TODO This works on command line.. load std.cfg? ASSERT_EQUALS("error", errout.str());
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's[10]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage(
"void fun(short data[2]) {\n"