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

Method virtualDestructor

lib/checkclass.cpp:2001–2134  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1999//---------------------------------------------------------------------------
2000
2001void CheckClassImpl::virtualDestructor()
2002{
2003 // This error should only be given if:
2004 // * base class doesn't have virtual destructor
2005 // * derived class has non-empty destructor (only c++03, in c++11 it's UB see paragraph 3 in [expr.delete])
2006 // * base class is deleted
2007 // unless inconclusive in which case:
2008 // * A class with any virtual functions should have a destructor that is either public and virtual or protected
2009 const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive);
2010
2011 std::list<const Function *> inconclusiveErrors;
2012
2013 logChecker("CheckClass::virtualDestructor");
2014
2015 for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
2016
2017 // Skip base classes (unless inconclusive)
2018 if (scope->definedType->derivedFrom.empty()) {
2019 if (printInconclusive) {
2020 const Function *destructor = scope->getDestructor();
2021 if (destructor && !destructor->hasVirtualSpecifier() && destructor->access == AccessControl::Public) {
2022 if (std::any_of(scope->functionList.cbegin(), scope->functionList.cend(), [](const Function& func) {
2023 return func.hasVirtualSpecifier();
2024 }))
2025 inconclusiveErrors.push_back(destructor);
2026 }
2027 }
2028 continue;
2029 }
2030
2031 // Check if destructor is empty and non-empty ..
2032 if (mSettings.standards.cpp <= Standards::CPP03) {
2033 // Find the destructor
2034 const Function *destructor = scope->getDestructor();
2035
2036 // Check for destructor with implementation
2037 if (!destructor || !destructor->hasBody())
2038 continue;
2039
2040 // Empty destructor
2041 if (destructor->token->linkAt(3) == destructor->token->tokAt(4))
2042 continue;
2043 }
2044
2045 const Token *derived = scope->classDef;
2046 const Token *derivedClass = derived->next();
2047
2048 // Iterate through each base class...
2049 for (const Type::BaseInfo & j : scope->definedType->derivedFrom) {
2050 // Check if base class is public and exists in database
2051 if (j.access != AccessControl::Private && j.type) {
2052 const Type *derivedFrom = j.type;
2053 const Scope *derivedFromScope = derivedFrom->classScope;
2054 if (!derivedFromScope)
2055 continue;
2056
2057 // Check for this pattern:
2058 // 1. Base class pointer is given the address of derived class instance

Callers 2

runChecksMethod · 0.80

Calls 15

getDestructorMethod · 0.80
linkAtMethod · 0.80
nextMethod · 0.80
typeMethod · 0.80
simpleMatchFunction · 0.70
isEnabledMethod · 0.45
emptyMethod · 0.45
push_backMethod · 0.45
tokAtMethod · 0.45
findMethod · 0.45
endMethod · 0.45
strMethod · 0.45

Tested by 1