MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / checkDuplicateBranch

Method checkDuplicateBranch

lib/checkother.cpp:2644–2721  ·  view source on GitHub ↗

----------------------------------------------------------------------------- check for duplicate code in if and else branches if (a) { b = true; } else { b = true; } -----------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

2642// if (a) { b = true; } else { b = true; }
2643//-----------------------------------------------------------------------------
2644void CheckOtherImpl::checkDuplicateBranch()
2645{
2646 // This is inconclusive since in practice most warnings are noise:
2647 // * There can be unfixed low-priority todos. The code is fine as it
2648 // is but it could be possible to enhance it. Writing a warning
2649 // here is noise since the code is fine (see cppcheck, abiword, ..)
2650 // * There can be overspecified code so some conditions can't be true
2651 // and their conditional code is a duplicate of the condition that
2652 // is always true just in case it would be false. See for instance
2653 // abiword.
2654 if (!mSettings.severity.isEnabled(Severity::style) || !mSettings.certainty.isEnabled(Certainty::inconclusive))
2655 return;
2656
2657 logChecker("CheckOther::checkDuplicateBranch"); // style,inconclusive
2658
2659 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
2660
2661 for (const Scope & scope : symbolDatabase->scopeList) {
2662 if (scope.type != ScopeType::eIf)
2663 continue;
2664
2665 // check all the code in the function for if (..) else
2666 if (Token::simpleMatch(scope.bodyEnd, "} else {")) {
2667 // Make sure there are no macros (different macros might be expanded
2668 // to the same code)
2669 bool macro = false;
2670 for (const Token *tok = scope.bodyStart; tok != scope.bodyEnd->linkAt(2); tok = tok->next()) {
2671 if (tok->isExpandedMacro()) {
2672 macro = true;
2673 break;
2674 }
2675 }
2676 if (macro)
2677 continue;
2678
2679 const Token * const tokIf = scope.bodyStart->next();
2680 const Token * const tokElse = scope.bodyEnd->tokAt(3);
2681
2682 // compare first tok before stringifying the whole blocks
2683 const std::string tokIfStr = tokIf->stringify(false, true, false);
2684 if (tokIfStr.empty())
2685 continue;
2686
2687 const std::string tokElseStr = tokElse->stringify(false, true, false);
2688
2689 if (tokIfStr == tokElseStr) {
2690 // save if branch code
2691 const std::string branch1 = tokIf->stringifyList(scope.bodyEnd);
2692
2693 if (branch1.empty())
2694 continue;
2695
2696 // save else branch code
2697 const std::string branch2 = tokElse->stringifyList(scope.bodyEnd->linkAt(2));
2698
2699 // check for duplicates
2700 if (branch1 == branch2 && branch1 != ";") {
2701 duplicateBranchError(scope.classDef, scope.bodyEnd->next(), ErrorPath{});

Callers 1

runChecksMethod · 0.80

Calls 13

isSameExpressionFunction · 0.85
linkAtMethod · 0.80
nextMethod · 0.80
stringifyListMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
simpleMatchFunction · 0.70
isEnabledMethod · 0.45
tokAtMethod · 0.45
stringifyMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected