23class RefCntblBaseVirtualDtorChecker
24 :
public Checker<check::ASTDecl<TranslationUnitDecl>> {
30 RefCntblBaseVirtualDtorChecker()
32 "Reference-countable base class doesn't have virtual destructor",
33 "WebKit coding guidelines") {}
43 const RefCntblBaseVirtualDtorChecker *
Checker;
44 explicit LocalVisitor(
const RefCntblBaseVirtualDtorChecker *
Checker)
49 bool shouldVisitTemplateInstantiations()
const {
return true; }
50 bool shouldVisitImplicitCode()
const {
return false; }
53 Checker->visitCXXRecordDecl(RD);
58 LocalVisitor visitor(
this);
63 if (shouldSkipDecl(RD))
72 const auto IsPublicBaseRefCntblWOVirtualDtor =
73 [RD, &ProblematicBaseSpecifier,
75 const auto AccSpec =
Base->getAccessSpecifier();
83 bool hasRef = hasRefInBase && *hasRefInBase !=
nullptr;
84 bool hasDeref = hasDerefInBase && *hasDerefInBase !=
nullptr;
93 bool AnyInconclusiveBase =
false;
94 const auto hasPublicRefInBase =
99 AnyInconclusiveBase =
true;
102 return (*hasRefInBase) !=
nullptr;
104 const auto hasPublicDerefInBase = [&AnyInconclusiveBase](
108 if (!hasDerefInBase) {
109 AnyInconclusiveBase =
true;
112 return (*hasDerefInBase) !=
nullptr;
116 hasRef = hasRef ||
C->lookupInBases(hasPublicRefInBase, Paths,
118 hasDeref = hasDeref ||
C->lookupInBases(hasPublicDerefInBase, Paths,
120 if (AnyInconclusiveBase || !hasRef || !hasDeref)
123 const auto *Dtor =
C->getDestructor();
124 if (!Dtor || !Dtor->isVirtual()) {
125 ProblematicBaseSpecifier =
Base;
126 ProblematicBaseClass =
C;
133 if (RD->
lookupInBases(IsPublicBaseRefCntblWOVirtualDtor, Paths,
135 reportBug(RD, ProblematicBaseSpecifier, ProblematicBaseClass);
152 if (!RDLocation.isValid())
156 if (Kind != TagTypeKind::Struct && Kind != TagTypeKind::Class)
170 assert(DerivedClass);
172 assert(ProblematicBaseClass);
175 llvm::raw_svector_ostream Os(Buf);
177 Os << (ProblematicBaseClass->
isClass() ?
"Class" :
"Struct") <<
" ";
180 Os <<
" is used as a base of "
181 << (DerivedClass->
isClass() ?
"class" :
"struct") <<
" ";
184 Os <<
" but doesn't have virtual destructor";
188 auto Report = std::make_unique<BasicBugReport>(Bug, Os.str(), BSLoc);
195void ento::registerRefCntblBaseVirtualDtorChecker(
CheckerManager &Mgr) {
199bool ento::shouldRegisterRefCntblBaseVirtualDtorChecker(
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
SourceLocation getBegin() const
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
TagKind getTagKind() const
The top declaration context.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
BugReporter is a utility class for generating PathDiagnostics for analysis.
const SourceManager & getSourceManager()
virtual void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
The JSON file list parser is used to communicate input to InstallAPI.
std::optional< const clang::CXXRecordDecl * > hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch)
void printQuotedQualifiedName(llvm::raw_ostream &Os, const NamedDeclDerivedT &D)