void CheckBool::checkComparisonOfBoolWithInt() { if (!_settings->isEnabled("warning") || !_tokenizer->isCPP()) return; const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { const Token* const left = tok->astOperand1(); const Token* const right = tok->astOperand2(); if (left && right && tok->isComparisonOp()) { if (left->isBoolean() && right->varId()) { // Comparing boolean constant with variable if (tok->str() != "==" && tok->str() != "!=") { comparisonOfBoolWithInvalidComparator(right, left->str()); } } else if (left->varId() && right->isBoolean()) { // Comparing variable with boolean constant if (tok->str() != "==" && tok->str() != "!=") { comparisonOfBoolWithInvalidComparator(right, left->str()); } } } } } }
void CheckBool::checkComparisonOfBoolWithInt() { if (!_settings->isEnabled("warning") || !_tokenizer->isCPP()) return; const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { const Token* const left = tok->astOperand1(); const Token* const right = tok->astOperand2(); if (left && right && tok->isComparisonOp()) { if ((left->varId() && right->isNumber()) || (left->isNumber() && right->varId())) { // Comparing variable with number const Token* varTok = left; const Token* numTok = right; if (left->isNumber() && right->varId()) // num with var std::swap(varTok, numTok); if (isBool(varTok->variable()) && // Variable has to be a boolean ((tok->str() != "==" && tok->str() != "!=") || (MathLib::toLongNumber(numTok->str()) != 0 && MathLib::toLongNumber(numTok->str()) != 1))) { // == 0 and != 0 are allowed, for C also == 1 and != 1 comparisonOfBoolWithIntError(varTok, numTok->str(), tok->str() == "==" || tok->str() == "!="); } } else if (left->isBoolean() && right->varId()) { // Comparing boolean constant with variable if (isNonBoolStdType(right->variable())) { // Variable has to be of non-boolean standard type comparisonOfBoolWithIntError(right, left->str(), false); } else if (tok->str() != "==" && tok->str() != "!=") { comparisonOfBoolWithInvalidComparator(right, left->str()); } } else if (left->varId() && right->isBoolean()) { // Comparing variable with boolean constant if (isNonBoolStdType(left->variable())) { // Variable has to be of non-boolean standard type comparisonOfBoolWithIntError(left, right->str(), false); } else if (tok->str() != "==" && tok->str() != "!=") { comparisonOfBoolWithInvalidComparator(right, left->str()); } } else if (left->isNumber() && right->isBoolean()) { // number constant with boolean constant comparisonOfBoolWithIntError(left, right->str(), false); } else if (left->isBoolean() && right->isNumber()) { // number constant with boolean constant comparisonOfBoolWithIntError(left, left->str(), false); } else if (left->varId() && right->varId()) { // Comparing two variables, one of them boolean, one of them integer const Variable* var1 = right->variable(); const Variable* var2 = left->variable(); if (isBool(var1) && isNonBoolStdType(var2)) // Comparing boolean with non-bool standard type comparisonOfBoolWithIntError(left, var1->name(), false); else if (isNonBoolStdType(var1) && isBool(var2)) // Comparing non-bool standard type with boolean comparisonOfBoolWithIntError(left, var2->name(), false); } } } } }