Merge pull request #665 from simartin/todo_condition

Fixed TODO-test for CheckCondition::checkBadBitmaskCheck by handling functions return bool.
This commit is contained in:
PKEuS 2015-09-03 22:53:33 +02:00
commit b49c5d7193
2 changed files with 49 additions and 2 deletions

View File

@ -217,6 +217,24 @@ static void getnumchildren(const Token *tok, std::list<MathLib::bigint> &numchil
getnumchildren(tok->astOperand2(), numchildren); getnumchildren(tok->astOperand2(), numchildren);
} }
/* Return whether tok is in the body for a function returning a boolean. */
static bool inBooleanFunction(const Token *tok)
{
const Scope *scope = tok ? tok->scope() : 0;
while (scope && scope->isLocal())
scope = scope->nestedIn;
if (scope && scope->type == Scope::eFunction) {
const Function *func = scope->function;
if (func) {
const Token *ret = func->retDef;
while (ret && Token::Match(ret, "static|const"))
ret = ret->next();
return ret && (ret->str() == "bool");
}
}
return false;
}
void CheckCondition::checkBadBitmaskCheck() void CheckCondition::checkBadBitmaskCheck()
{ {
if (!_settings->isEnabled("warning")) if (!_settings->isEnabled("warning"))
@ -228,7 +246,8 @@ void CheckCondition::checkBadBitmaskCheck()
const bool isBoolean = Token::Match(parent, "&&|%oror%") || const bool isBoolean = Token::Match(parent, "&&|%oror%") ||
(parent->str() == "?" && parent->astOperand1() == tok) || (parent->str() == "?" && parent->astOperand1() == tok) ||
(parent->str() == "=" && parent->astOperand2() == tok && parent->astOperand1() && parent->astOperand1()->variable() && parent->astOperand1()->variable()->typeStartToken()->str() == "bool") || (parent->str() == "=" && parent->astOperand2() == tok && parent->astOperand1() && parent->astOperand1()->variable() && parent->astOperand1()->variable()->typeStartToken()->str() == "bool") ||
(parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")); (parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) ||
(parent->str() == "return" && parent->astOperand1() == tok && inBooleanFunction(tok));
const bool isTrue = (tok->astOperand1()->values.size() == 1 && tok->astOperand1()->values.front().intvalue != 0 && !tok->astOperand1()->values.front().conditional) || const bool isTrue = (tok->astOperand1()->values.size() == 1 && tok->astOperand1()->values.front().intvalue != 0 && !tok->astOperand1()->values.front().conditional) ||
(tok->astOperand2()->values.size() == 1 && tok->astOperand2()->values.front().intvalue != 0 && !tok->astOperand2()->values.front().conditional); (tok->astOperand2()->values.size() == 1 && tok->astOperand2()->values.front().intvalue != 0 && !tok->astOperand2()->values.front().conditional);

View File

@ -528,7 +528,35 @@ private:
check("bool f(int x) {\n" check("bool f(int x) {\n"
" return x | 0x02;\n" " return x | 0x02;\n"
"}"); "}");
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", "", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout.str());
check("bool f(int x) {\n"
" if (x) {\n"
" return x | 0x02;\n"
" }\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout.str());
check("const bool f(int x) {\n"
" return x | 0x02;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout.str());
check("struct F {\n"
" static const bool f(int x) {\n"
" return x | 0x02;\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout.str());
check("struct F {\n"
" typedef bool b_t;\n"
"};\n"
"F::b_t f(int x) {\n"
" return x | 0x02;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout.str());
check("int f(int x) {\n" check("int f(int x) {\n"
" return x | 0x02;\n" " return x | 0x02;\n"