| 593 | //--------------------------------------------------------------------------- |
| 594 | |
| 595 | void CheckOtherImpl::checkRedundantAssignment() |
| 596 | { |
| 597 | if (!mSettings.severity.isEnabled(Severity::style) && |
| 598 | !mSettings.isPremiumEnabled("redundantAssignment") && |
| 599 | !mSettings.isPremiumEnabled("redundantAssignInSwitch")) |
| 600 | return; |
| 601 | |
| 602 | logChecker("CheckOther::checkRedundantAssignment"); // style |
| 603 | |
| 604 | const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 605 | for (const Scope *scope : symbolDatabase->functionScopes) { |
| 606 | if (!scope->bodyStart) |
| 607 | continue; |
| 608 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 609 | if (Token::simpleMatch(tok, "] (")) |
| 610 | // todo: handle lambdas |
| 611 | break; |
| 612 | if (Token::simpleMatch(tok, "try {")) |
| 613 | // todo: check try blocks |
| 614 | tok = tok->linkAt(1); |
| 615 | if ((tok->isAssignmentOp() || tok->tokType() == Token::eIncDecOp) && tok->astOperand1()) { |
| 616 | if (tok->astParent()) |
| 617 | continue; |
| 618 | |
| 619 | // Do not warn about redundant initialization when rhs is trivial |
| 620 | // TODO : do not simplify the variable declarations |
| 621 | bool isInitialization = false; |
| 622 | if (Token::Match(tok->tokAt(-2), "; %var% =") && tok->tokAt(-2)->isSplittedVarDeclEq()) { |
| 623 | isInitialization = true; |
| 624 | bool trivial = true; |
| 625 | visitAstNodes(tok->astOperand2(), |
| 626 | [&](const Token *rhs) { |
| 627 | if (Token::simpleMatch(rhs, "{ 0 }")) |
| 628 | return ChildrenToVisit::none; |
| 629 | if (Token::Match(rhs, "%num%|%name%") && !rhs->varId()) |
| 630 | return ChildrenToVisit::none; |
| 631 | if (Token::Match(rhs, ":: %name%") && rhs->hasKnownIntValue()) |
| 632 | return ChildrenToVisit::none; |
| 633 | if (rhs->isCast()) |
| 634 | return ChildrenToVisit::op2; |
| 635 | trivial = false; |
| 636 | return ChildrenToVisit::done; |
| 637 | }); |
| 638 | if (trivial) |
| 639 | continue; |
| 640 | } |
| 641 | |
| 642 | const Token* rhs = tok->astOperand2(); |
| 643 | // Do not warn about assignment with 0 / NULL |
| 644 | if ((rhs && MathLib::isNullValue(rhs->str())) || isNullOperand(rhs)) |
| 645 | continue; |
| 646 | |
| 647 | if (tok->astOperand1()->variable() && tok->astOperand1()->variable()->isReference()) |
| 648 | // todo: check references |
| 649 | continue; |
| 650 | |
| 651 | if (tok->astOperand1()->variable() && tok->astOperand1()->variable()->isStatic()) |
| 652 | // todo: check static variables |
no test coverage detected