Fix false negatives in checkAssignBoolToFloat and minor related improvements (#2198)

* Fix false negatives in checkAssignBoolToFloat

Detect assignments to expressions involving pointer dereferences, array
element accesses, etc.

* Pass assignment token to assignBoolToFloatError

Pass assignment token rather than boolean token to make error reporting
consistent between checkAssignBoolToFloat and checkAssignBoolToPointer,
as well as with other assignment checks in the code base.

* Make checkAssignBoolToPointer check consistent with checkAssignBoolToFloat
This commit is contained in:
Tyson Nottingham 2019-09-20 23:24:54 -07:00 committed by Daniel Marjamäki
parent 40f1635c35
commit d6a70d27c7
2 changed files with 14 additions and 19 deletions

View File

@ -289,16 +289,9 @@ void CheckBool::checkAssignBoolToPointer()
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
if (tok->str() != "=") if (tok->str() == "=" && astIsPointer(tok->astOperand1()) && astIsBool(tok->astOperand2())) {
continue; assignBoolToPointerError(tok);
const ValueType *lhsType = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr; }
if (!lhsType || lhsType->pointer == 0)
continue;
const ValueType *rhsType = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr;
if (!rhsType || rhsType->pointer > 0 || rhsType->type != ValueType::Type::BOOL)
continue;
assignBoolToPointerError(tok);
} }
} }
} }
@ -436,15 +429,8 @@ void CheckBool::checkAssignBoolToFloat()
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
if (tok->str() == "=" && astIsBool(tok->astOperand2())) { if (tok->str() == "=" && astIsFloat(tok->astOperand1(), false) && astIsBool(tok->astOperand2())) {
const Token *lhs = tok->astOperand1(); assignBoolToFloatError(tok);
while (lhs && (lhs->str() == "." || lhs->str() == "::"))
lhs = lhs->astOperand2();
if (!lhs || !lhs->variable())
continue;
const Variable* var = lhs->variable();
if (var && var->isFloatingType() && !var->isArrayOrPointer())
assignBoolToFloatError(tok->next());
} }
} }
} }

View File

@ -212,6 +212,15 @@ private:
" s.p = true;\n" " s.p = true;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (style) Boolean value assigned to floating point variable.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (style) Boolean value assigned to floating point variable.\n", errout.str());
check("struct S {\n"
" float* p[1];\n"
"};\n"
"void f() {\n"
" S s = {0};\n"
" *s.p[0] = true;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (style) Boolean value assigned to floating point variable.\n", errout.str());
} }
void comparisonOfBoolExpressionWithInt1() { void comparisonOfBoolExpressionWithInt1() {