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

Method checkUselessOverride

lib/checkclass.cpp:3421–3479  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3419}
3420
3421void CheckClassImpl::checkUselessOverride()
3422{
3423 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("uselessOverride"))
3424 return;
3425
3426 logChecker("CheckClass::checkUselessOverride"); // style
3427
3428 for (const Scope* classScope : mSymbolDatabase->classAndStructScopes) {
3429 if (!classScope->definedType || classScope->definedType->derivedFrom.size() != 1)
3430 continue;
3431 for (const Function& func : classScope->functionList) {
3432 if (!func.functionScope)
3433 continue;
3434 if (func.hasFinalSpecifier())
3435 continue;
3436 const Function* baseFunc = func.getOverriddenFunction();
3437 if (!baseFunc || baseFunc->isPure() || baseFunc->access != func.access)
3438 continue;
3439 if (std::any_of(classScope->functionList.begin(), classScope->functionList.end(), [&func](const Function& f) { // check for overloads
3440 if (&f == &func)
3441 return false;
3442 return f.name() == func.name();
3443 }))
3444 continue;
3445 if (func.token->isExpandedMacro() || baseFunc->token->isExpandedMacro())
3446 continue;
3447 if (baseFunc->functionScope) {
3448 bool isSameCode = compareTokenRanges(baseFunc->argDef, baseFunc->argDef->link(), func.argDef, func.argDef->link()); // function arguments
3449 if (isSameCode) {
3450 isSameCode = compareTokenRanges(baseFunc->functionScope->bodyStart, baseFunc->functionScope->bodyEnd, // function body
3451 func.functionScope->bodyStart, func.functionScope->bodyEnd);
3452
3453 if (isSameCode) {
3454 // bailout for shadowed members
3455 if (!classScope->definedType ||
3456 !getDuplInheritedMembersRecursive(classScope->definedType, classScope->definedType, /*skipPrivate*/ false).empty() ||
3457 !getDuplInheritedMemberFunctionsRecursive(classScope->definedType, classScope->definedType, /*skipPrivate*/ false).empty())
3458 continue;
3459 uselessOverrideError(baseFunc, &func, true);
3460 continue;
3461 }
3462 }
3463 }
3464 if (const Token* const call = getSingleFunctionCall(func.functionScope)) {
3465 if (call->function() != baseFunc)
3466 continue;
3467 if (Token::simpleMatch(call->astParent(), "."))
3468 continue;
3469 std::vector<const Token*> callArgs = getArguments(call);
3470 if (func.argumentList.size() != callArgs.size() ||
3471 !std::equal(func.argumentList.begin(), func.argumentList.end(), callArgs.begin(), [](const Variable& v, const Token* t) {
3472 return v.nameToken() && v.nameToken()->str() == t->str();
3473 }))
3474 continue;
3475 uselessOverrideError(baseFunc, &func);
3476 }
3477 }
3478 }

Callers 1

runChecksMethod · 0.80

Calls 15

compareTokenRangesFunction · 0.85
getSingleFunctionCallFunction · 0.85
isPremiumEnabledMethod · 0.80
getOverriddenFunctionMethod · 0.80
isPureMethod · 0.80
astParentMethod · 0.80
simpleMatchFunction · 0.70
getArgumentsFunction · 0.70
isEnabledMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected