Improve check: warn when comparing boolean value with < <= > >=. Ticket: #2617

This commit is contained in:
Robert Morin 2012-07-03 06:39:13 +02:00 committed by Daniel Marjamäki
parent f72ddbb2e9
commit 25c1cc4c8e
3 changed files with 70 additions and 0 deletions

View File

@ -1341,10 +1341,14 @@ void CheckOther::checkComparisonOfBoolWithInt()
} else if (tok->isBoolean() && right->varId()) { // Comparing boolean constant with variable
if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(right->varId()))) { // Variable has to be of non-boolean standard type
comparisonOfBoolWithIntError(right, tok->str(), false);
} else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") {
comparisonOfBoolWithInvalidComparator(right, tok->str());
}
} else if (tok->varId() && right->isBoolean()) { // Comparing variable with boolean constant
if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(tok->varId()))) { // Variable has to be of non-boolean standard type
comparisonOfBoolWithIntError(tok, right->str(), false);
} else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") {
comparisonOfBoolWithInvalidComparator(right, tok->str());
}
} else if (tok->isNumber() && right->isBoolean()) { // number constant with boolean constant
comparisonOfBoolWithIntError(tok, right->str(), false);
@ -1377,6 +1381,15 @@ void CheckOther::comparisonOfBoolWithIntError(const Token *tok, const std::strin
"and it is compared against a integer value.");
}
void CheckOther::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression)
{
reportError(tok, Severity::warning, "comparisonOfBoolWithInvalidComparator",
"Comparison of a boolean value using relational (<, >, <= or >=) operator.\n"
"The expression \"" + expression + "\" is of type 'bool' "
"and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)"
" operator could cause unexpected results.");
}
//---------------------------------------------------------------------------
// Find consecutive return, break, continue, goto or throw statements. e.g.:
// break; break;

View File

@ -273,6 +273,7 @@ private:
void incorrectStringBooleanError(const Token *tok, const std::string& string);
void incrementBooleanError(const Token *tok);
void comparisonOfBoolWithIntError(const Token *tok, const std::string &expression, bool n0o1);
void comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression);
void duplicateIfError(const Token *tok1, const Token *tok2);
void duplicateBranchError(const Token *tok1, const Token *tok2);
void duplicateExpressionError(const Token *tok1, const Token *tok2, const std::string &op);

View File

@ -3205,6 +3205,62 @@ private:
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str());
check("void f(bool x ) {\n"
" if ( x > false )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( false < x )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( x < false )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( false > x )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( x >= false )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( false >= x )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( x <= false )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("void f(bool x ) {\n"
" if ( false >= x )\n"
" a++;\n"
"}\n"
);
ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str());
check("typedef int (*func)(bool invert);\n"
"void x(int, func f);\n"
"void foo(int error) {\n"