--------------------------------------------------------------------------- Clarify condition '(x = a < 0)' into '((x = a) < 0)' or '(x = (a < 0))' Clarify condition '(a & b == c)' into '((a & b) == c)' or '(a & (b == c))' ---------------------------------------------------------------------------
| 1451 | // Clarify condition '(a & b == c)' into '((a & b) == c)' or '(a & (b == c))' |
| 1452 | //--------------------------------------------------------------------------- |
| 1453 | void CheckConditionImpl::clarifyCondition() |
| 1454 | { |
| 1455 | if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("clarifyCondition")) |
| 1456 | return; |
| 1457 | |
| 1458 | logChecker("CheckCondition::clarifyCondition"); // style |
| 1459 | |
| 1460 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 1461 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 1462 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 1463 | if (Token::Match(tok, "( %name% [=&|^]")) { |
| 1464 | for (const Token *tok2 = tok->tokAt(3); tok2; tok2 = tok2->next()) { |
| 1465 | if (tok2->str() == "(" || tok2->str() == "[") |
| 1466 | tok2 = tok2->link(); |
| 1467 | else if (tok2->isComparisonOp()) { |
| 1468 | // This might be a template |
| 1469 | if (!tok2->isC() && tok2->link()) |
| 1470 | break; |
| 1471 | if (Token::simpleMatch(tok2->astParent(), "?")) |
| 1472 | break; |
| 1473 | clarifyConditionError(tok, tok->strAt(2) == "=", false); |
| 1474 | break; |
| 1475 | } else if (!tok2->isName() && !tok2->isNumber() && tok2->str() != ".") |
| 1476 | break; |
| 1477 | } |
| 1478 | } else if (tok->tokType() == Token::eBitOp && !tok->isUnaryOp("&")) { |
| 1479 | if (tok->astOperand2() && tok->astOperand2()->variable() && tok->astOperand2()->variable()->nameToken() == tok->astOperand2()) |
| 1480 | continue; |
| 1481 | |
| 1482 | // using boolean result in bitwise operation ! x [&|^] |
| 1483 | const ValueType* vt1 = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr; |
| 1484 | const ValueType* vt2 = tok->astOperand2() ? tok->astOperand2()->valueType() : nullptr; |
| 1485 | if (vt1 && vt1->type == ValueType::BOOL && !Token::Match(tok->astOperand1(), "%name%|(|[|::|.") && countPar(tok->astOperand1(), tok) == 0) |
| 1486 | clarifyConditionError(tok, false, true); |
| 1487 | else if (vt2 && vt2->type == ValueType::BOOL && !Token::Match(tok->astOperand2(), "%name%|(|[|::|.") && countPar(tok, tok->astOperand2()) == 0) |
| 1488 | clarifyConditionError(tok, false, true); |
| 1489 | } |
| 1490 | } |
| 1491 | } |
| 1492 | } |
| 1493 | |
| 1494 | void CheckConditionImpl::clarifyConditionError(const Token *tok, bool assign, bool boolop) |
| 1495 | { |
no test coverage detected