* Fix #7197 not getting expected warning in relational comparison of booleans * return nullptr
This commit is contained in:
parent
e9641e6de5
commit
942dbad11c
|
@ -172,7 +172,7 @@ void CheckBool::comparisonOfBoolWithInvalidComparator(const Token *tok, const st
|
|||
|
||||
static bool tokenIsFunctionReturningBool(const Token* tok)
|
||||
{
|
||||
const Function* func = tok->function();
|
||||
const Function* func = tok ? tok->function() : nullptr;
|
||||
if (func && Token::Match(tok, "%name% (")) {
|
||||
if (func->tokenDef && Token::Match(func->tokenDef->previous(), "bool|_Bool")) {
|
||||
return true;
|
||||
|
@ -190,19 +190,26 @@ void CheckBool::checkComparisonOfFuncReturningBool()
|
|||
return;
|
||||
|
||||
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
|
||||
auto getFunctionTok = [](const Token* tok) -> const Token* {
|
||||
while (Token::simpleMatch(tok, "!") || (tok && tok->isCast() && !isCPPCast(tok)))
|
||||
tok = tok->astOperand1();
|
||||
if (isCPPCast(tok))
|
||||
tok = tok->astOperand2();
|
||||
if (tok)
|
||||
return tok->previous();
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
for (const Scope * scope : symbolDatabase->functionScopes) {
|
||||
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
|
||||
if (!tok->isComparisonOp() || tok->str() == "==" || tok->str() == "!=")
|
||||
continue;
|
||||
const Token *firstToken = tok->previous();
|
||||
if (tok->strAt(-1) == ")") {
|
||||
firstToken = firstToken->link()->previous();
|
||||
}
|
||||
const Token *secondToken = tok->next();
|
||||
while (secondToken->str() == "!") {
|
||||
secondToken = secondToken->next();
|
||||
}
|
||||
|
||||
const Token* firstToken = getFunctionTok(tok->astOperand1());
|
||||
const Token* secondToken = getFunctionTok(tok->astOperand2());
|
||||
if (!firstToken || !secondToken)
|
||||
continue;
|
||||
|
||||
const bool firstIsFunctionReturningBool = tokenIsFunctionReturningBool(firstToken);
|
||||
const bool secondIsFunctionReturningBool = tokenIsFunctionReturningBool(secondToken);
|
||||
if (firstIsFunctionReturningBool && secondIsFunctionReturningBool) {
|
||||
|
|
|
@ -63,6 +63,7 @@ private:
|
|||
TEST_CASE(checkComparisonOfFuncReturningBool4);
|
||||
TEST_CASE(checkComparisonOfFuncReturningBool5);
|
||||
TEST_CASE(checkComparisonOfFuncReturningBool6);
|
||||
TEST_CASE(checkComparisonOfFuncReturningBool7); // #7197
|
||||
// Integration tests..
|
||||
TEST_CASE(checkComparisonOfFuncReturningBoolIntegrationTest1); // #7798 overloaded functions
|
||||
|
||||
|
@ -710,6 +711,24 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void checkComparisonOfFuncReturningBool7() { // #7197
|
||||
check("struct C {\n"
|
||||
" bool isEmpty();\n"
|
||||
"};\n"
|
||||
"void f() {\n"
|
||||
" C c1, c2;\n"
|
||||
" if ((c1.isEmpty()) < (c2.isEmpty())) {}\n"
|
||||
" if (!c1.isEmpty() < !!c2.isEmpty()) {}\n"
|
||||
" if ((int)c1.isEmpty() < (int)c2.isEmpty()) {}\n"
|
||||
" if (static_cast<int>(c1.isEmpty()) < static_cast<int>(c2.isEmpty())) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
|
||||
"[test.cpp:7]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
|
||||
"[test.cpp:8]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
|
||||
"[test.cpp:9]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n",
|
||||
errout.str());
|
||||
}
|
||||
|
||||
void checkComparisonOfFuncReturningBoolIntegrationTest1() { // #7798
|
||||
check("bool eval(double *) { return false; }\n"
|
||||
"double eval(char *) { return 1.0; }\n"
|
||||
|
|
Loading…
Reference in New Issue