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

Method checkStructMemberUsage

lib/checkunusedvar.cpp:1520–1700  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Check that all struct members are used ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

1518// Check that all struct members are used
1519//---------------------------------------------------------------------------
1520void CheckUnusedVarImpl::checkStructMemberUsage()
1521{
1522 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedStructMember") && !mSettings.isPremiumEnabled("unusedVariable"))
1523 return;
1524
1525 logChecker("CheckUnusedVar::checkStructMemberUsage"); // style
1526
1527 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
1528
1529 for (const Scope &scope : symbolDatabase->scopeList) {
1530 if (scope.type != ScopeType::eStruct && scope.type != ScopeType::eClass && scope.type != ScopeType::eUnion)
1531 continue;
1532
1533 if (scope.bodyStart->fileIndex() != 0 || scope.className.empty())
1534 continue;
1535
1536 if (scope.classDef->isExpandedMacro())
1537 continue;
1538
1539 // Packed struct => possibly used by lowlevel code. Struct members might be required by hardware.
1540 if (scope.bodyEnd->isAttributePacked())
1541 continue;
1542 if (mTokenizer->isPacked(scope.bodyStart))
1543 continue;
1544
1545 // Bail out for template struct, members might be used in non-matching instantiations
1546 if (scope.className.find('<') != std::string::npos)
1547 continue;
1548
1549 // bail out if struct is inherited
1550 const bool isInherited = std::any_of(symbolDatabase->scopeList.cbegin(), symbolDatabase->scopeList.cend(), [&](const Scope& derivedScope) {
1551 const Type* dType = derivedScope.definedType;
1552 return dType && std::any_of(dType->derivedFrom.cbegin(), dType->derivedFrom.cend(), [&](const Type::BaseInfo& derivedFrom) {
1553 return derivedFrom.type == scope.definedType && derivedFrom.access != AccessControl::Private;
1554 });
1555 });
1556
1557 // bail out for extern/global struct
1558 bool bailout = false;
1559 for (const Variable* var : symbolDatabase->variableList()) {
1560 if (var && (var->isExtern() || (var->isGlobal() && !var->isStatic())) && var->typeEndToken()->str() == scope.className) {
1561 bailout = true;
1562 break;
1563 }
1564 if (bailout)
1565 break;
1566 }
1567 if (bailout)
1568 continue;
1569
1570 // Bail out if some data is casted to struct..
1571 const std::string castPattern("( struct| " + scope.className + " * ) &| %name%");
1572 if (Token::findmatch(scope.bodyEnd, castPattern.c_str()))
1573 continue;
1574
1575 // (struct S){..}
1576 const std::string initPattern("( struct| " + scope.className + " ) {");
1577 if (Token::findmatch(scope.bodyEnd, initPattern.c_str()))

Callers 1

runChecksMethod · 0.80

Calls 15

findsimplematchFunction · 0.85
astIsContainerFunction · 0.85
astIsSmartPointerFunction · 0.85
isPremiumEnabledMethod · 0.80
fileIndexMethod · 0.80
isPackedMethod · 0.80
linkAtMethod · 0.80
astOperand2Method · 0.80
nextMethod · 0.80
typeMethod · 0.80
variableMethod · 0.80
scopeMethod · 0.80

Tested by

no test coverage detected