parent
f28d5e91ac
commit
43db6147d3
|
@ -1009,7 +1009,7 @@ void CheckIO::checkFormatString(const Token * const tok,
|
||||||
} else if (argInfo.typeToken->str() != "long" || argInfo.typeToken->isLong())
|
} else if (argInfo.typeToken->str() != "long" || argInfo.typeToken->isLong())
|
||||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||||
else if (typesMatch(argInfo.typeToken->originalName(), "size_t") ||
|
else if (typesMatch(argInfo.typeToken->originalName(), "size_t") ||
|
||||||
argInfo.typeToken->originalName() == "uintmax_t")
|
argInfo.typeToken->originalName() == "uintmax_t")
|
||||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
|
|
|
@ -346,75 +346,75 @@ void CheckString::overlappingStringComparisons()
|
||||||
for (std::size_t i = 0; i < functions; ++i) {
|
for (std::size_t i = 0; i < functions; ++i) {
|
||||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||||
if (tok->str() != "||")
|
if (tok->str() != "||")
|
||||||
continue;
|
continue;
|
||||||
std::list<const Token *> equals0;
|
std::list<const Token *> equals0;
|
||||||
std::list<const Token *> notEquals0;
|
std::list<const Token *> notEquals0;
|
||||||
std::stack<const Token *> tokens;
|
std::stack<const Token *> tokens;
|
||||||
tokens.push(tok);
|
tokens.push(tok);
|
||||||
while (!tokens.empty()) {
|
while (!tokens.empty()) {
|
||||||
const Token * const t = tokens.top();
|
const Token * const t = tokens.top();
|
||||||
tokens.pop();
|
tokens.pop();
|
||||||
if (!t)
|
if (!t)
|
||||||
continue;
|
continue;
|
||||||
if (t->str() == "||") {
|
if (t->str() == "||") {
|
||||||
tokens.push(t->astOperand1());
|
tokens.push(t->astOperand1());
|
||||||
tokens.push(t->astOperand2());
|
tokens.push(t->astOperand2());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t->str() == "==") {
|
if (t->str() == "==") {
|
||||||
if (Token::simpleMatch(t->astOperand1(), "(") && Token::simpleMatch(t->astOperand2(), "0"))
|
if (Token::simpleMatch(t->astOperand1(), "(") && Token::simpleMatch(t->astOperand2(), "0"))
|
||||||
equals0.push_back(t->astOperand1());
|
equals0.push_back(t->astOperand1());
|
||||||
else if (Token::simpleMatch(t->astOperand2(), "(") && Token::simpleMatch(t->astOperand1(), "0"))
|
else if (Token::simpleMatch(t->astOperand2(), "(") && Token::simpleMatch(t->astOperand1(), "0"))
|
||||||
equals0.push_back(t->astOperand2());
|
equals0.push_back(t->astOperand2());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t->str() == "!=") {
|
if (t->str() == "!=") {
|
||||||
if (Token::simpleMatch(t->astOperand1(), "(") && Token::simpleMatch(t->astOperand2(), "0"))
|
if (Token::simpleMatch(t->astOperand1(), "(") && Token::simpleMatch(t->astOperand2(), "0"))
|
||||||
notEquals0.push_back(t->astOperand1());
|
notEquals0.push_back(t->astOperand1());
|
||||||
else if (Token::simpleMatch(t->astOperand2(), "(") && Token::simpleMatch(t->astOperand1(), "0"))
|
else if (Token::simpleMatch(t->astOperand2(), "(") && Token::simpleMatch(t->astOperand1(), "0"))
|
||||||
notEquals0.push_back(t->astOperand2());
|
notEquals0.push_back(t->astOperand2());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t->str() == "!" && Token::simpleMatch(t->astOperand1(), "("))
|
if (t->str() == "!" && Token::simpleMatch(t->astOperand1(), "("))
|
||||||
equals0.push_back(t->astOperand1());
|
equals0.push_back(t->astOperand1());
|
||||||
else if (t->str() == "(")
|
else if (t->str() == "(")
|
||||||
notEquals0.push_back(t);
|
notEquals0.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
for (std::list<const Token *>::const_iterator eq0 = equals0.begin(); !error && eq0 != equals0.end(); ++eq0) {
|
for (std::list<const Token *>::const_iterator eq0 = equals0.begin(); !error && eq0 != equals0.end(); ++eq0) {
|
||||||
for (std::list<const Token *>::const_iterator ne0 = notEquals0.begin(); !error && ne0 != notEquals0.end(); ++ne0) {
|
for (std::list<const Token *>::const_iterator ne0 = notEquals0.begin(); !error && ne0 != notEquals0.end(); ++ne0) {
|
||||||
const Token *tok1 = *eq0;
|
const Token *tok1 = *eq0;
|
||||||
const Token *tok2 = *ne0;
|
const Token *tok2 = *ne0;
|
||||||
if (!Token::simpleMatch(tok1->previous(), "strcmp ("))
|
if (!Token::simpleMatch(tok1->previous(), "strcmp ("))
|
||||||
continue;
|
continue;
|
||||||
if (!Token::simpleMatch(tok2->previous(), "strcmp ("))
|
if (!Token::simpleMatch(tok2->previous(), "strcmp ("))
|
||||||
continue;
|
continue;
|
||||||
const std::vector<const Token *> args1 = getArguments(tok1->previous());
|
const std::vector<const Token *> args1 = getArguments(tok1->previous());
|
||||||
const std::vector<const Token *> args2 = getArguments(tok2->previous());
|
const std::vector<const Token *> args2 = getArguments(tok2->previous());
|
||||||
if (args1.size() != 2 || args2.size() != 2)
|
if (args1.size() != 2 || args2.size() != 2)
|
||||||
continue;
|
continue;
|
||||||
if (args1[1]->isLiteral() &&
|
if (args1[1]->isLiteral() &&
|
||||||
args2[1]->isLiteral() &&
|
args2[1]->isLiteral() &&
|
||||||
args1[1]->str() != args2[1]->str() &&
|
args1[1]->str() != args2[1]->str() &&
|
||||||
isSameExpression(_tokenizer->isCPP(), true, args1[0], args2[0], _settings->library, true))
|
isSameExpression(_tokenizer->isCPP(), true, args1[0], args2[0], _settings->library, true))
|
||||||
overlappingStringComparisonsError(tok1, tok2);
|
overlappingStringComparisonsError(tok1, tok2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckString::overlappingStringComparisonsError(const Token *eq0, const Token *ne0)
|
void CheckString::overlappingStringComparisonsError(const Token *eq0, const Token *ne0)
|
||||||
{
|
{
|
||||||
std::string eq0Expr(eq0 ? eq0->expressionString() : std::string("strcmp(x,\"abc\")"));
|
std::string eq0Expr(eq0 ? eq0->expressionString() : std::string("strcmp(x,\"abc\")"));
|
||||||
if (eq0 && eq0->astParent()->str() == "!")
|
if (eq0 && eq0->astParent()->str() == "!")
|
||||||
eq0Expr = "!" + eq0Expr;
|
eq0Expr = "!" + eq0Expr;
|
||||||
else
|
else
|
||||||
eq0Expr += " == 0";
|
eq0Expr += " == 0";
|
||||||
const std::string ne0Expr = (ne0 ? ne0->expressionString() : std::string("strcmp(x,\"def\")")) + " != 0";
|
const std::string ne0Expr = (ne0 ? ne0->expressionString() : std::string("strcmp(x,\"def\")")) + " != 0";
|
||||||
reportError(ne0, Severity::warning, "overlappingStringComparisons", "The comparison operator in '" + ne0Expr + "' should maybe be '==' instead, currently the expression '" + eq0Expr + "' is redundant.");
|
reportError(ne0, Severity::warning, "overlappingStringComparisons", "The comparison operator in '" + ne0Expr + "' should maybe be '==' instead, currently the expression '" + eq0Expr + "' is redundant.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -564,11 +564,11 @@ private:
|
||||||
|
|
||||||
void garbageCode36() { // #6334
|
void garbageCode36() { // #6334
|
||||||
ASSERT_THROW(checkCode("{ } < class template < > , { = } ; class... >\n"
|
ASSERT_THROW(checkCode("{ } < class template < > , { = } ; class... >\n"
|
||||||
"struct Y { }\n"
|
"struct Y { }\n"
|
||||||
"class Types { }\n"
|
"class Types { }\n"
|
||||||
"( X < int > \"uses template\" ) ( < ( ) \"uses ;"
|
"( X < int > \"uses template\" ) ( < ( ) \"uses ;"
|
||||||
"( int int ::primary \"uses template\" ) int double \"uses )"
|
"( int int ::primary \"uses template\" ) int double \"uses )"
|
||||||
"::primary , \"uses template\" ;\n"), InternalError);
|
"::primary , \"uses template\" ;\n"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode37() {
|
void garbageCode37() {
|
||||||
|
|
|
@ -51,7 +51,7 @@ private:
|
||||||
TEST_CASE(sprintf4); // struct member
|
TEST_CASE(sprintf4); // struct member
|
||||||
|
|
||||||
TEST_CASE(incorrectStringCompare);
|
TEST_CASE(incorrectStringCompare);
|
||||||
|
|
||||||
TEST_CASE(overlappingStringComparisons);
|
TEST_CASE(overlappingStringComparisons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,13 +581,13 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlappingStringComparisons() {
|
void overlappingStringComparisons() {
|
||||||
check("void f(const char *str) {\n"
|
check("void f(const char *str) {\n"
|
||||||
" if (strcmp(str, \"abc\") == 0 || strcmp(str, \"def\")) {}\n"
|
" if (strcmp(str, \"abc\") == 0 || strcmp(str, \"def\")) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) The comparison operator in 'strcmp(str,\"def\") != 0' should maybe be '==' instead, currently the expression 'strcmp(str,\"abc\") == 0' is redundant.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) The comparison operator in 'strcmp(str,\"def\") != 0' should maybe be '==' instead, currently the expression 'strcmp(str,\"abc\") == 0' is redundant.\n", errout.str());
|
||||||
|
|
||||||
check("struct X {\n"
|
check("struct X {\n"
|
||||||
" char *str;\n"
|
" char *str;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -595,7 +595,7 @@ private:
|
||||||
" if (strcmp(x->str, \"abc\") == 0 || strcmp(x->str, \"def\")) {}\n"
|
" if (strcmp(x->str, \"abc\") == 0 || strcmp(x->str, \"def\")) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (warning) The comparison operator in 'strcmp(x->str,\"def\") != 0' should maybe be '==' instead, currently the expression 'strcmp(x->str,\"abc\") == 0' is redundant.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (warning) The comparison operator in 'strcmp(x->str,\"def\") != 0' should maybe be '==' instead, currently the expression 'strcmp(x->str,\"abc\") == 0' is redundant.\n", errout.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestString)
|
REGISTER_TEST(TestString)
|
||||||
|
|
Loading…
Reference in New Issue