46class CXXDeleteChecker :
public Checker<check::PreStmt<CXXDeleteExpr>> {
50 void Profile(llvm::FoldingSetNodeID &ID)
const override {
68class DeleteWithNonVirtualDtorChecker :
public CXXDeleteChecker {
70 this,
"Destruction of a polymorphic object with no virtual destructor"};
78class CXXArrayDeleteChecker :
public CXXDeleteChecker {
80 "Deleting an array of polymorphic objects is undefined"};
92 const MemRegion *MR =
C.getSVal(DeletedObj).getAsRegion();
99 if (DeleteKind != OO_Delete && DeleteKind != OO_Array_Delete)
104 if (!BaseClassRegion || !DerivedClassRegion)
107 checkTypedDeleteExpr(DE,
C, BaseClassRegion, DerivedClassRegion);
110void DeleteWithNonVirtualDtorChecker::checkTypedDeleteExpr(
115 const auto *DerivedClass =
117 if (!BaseClass || !DerivedClass)
120 if (!BaseClass->hasDefinition() || !DerivedClass->hasDefinition())
123 if (BaseClass->getDestructor()->isVirtual())
126 if (!DerivedClass->isDerivedFrom(BaseClass))
132 auto R = std::make_unique<PathSensitiveBugReport>(BT, BT.getDescription(), N);
135 R->markInteresting(BaseClassRegion);
136 R->addVisitor<PtrCastVisitor>();
137 C.emitReport(std::move(R));
140void CXXArrayDeleteChecker::checkTypedDeleteExpr(
145 const auto *DerivedClass =
147 if (!BaseClass || !DerivedClass)
150 if (!BaseClass->hasDefinition() || !DerivedClass->hasDefinition())
156 if (!DerivedClass->isDerivedFrom(BaseClass))
164 llvm::raw_svector_ostream OS(Buf);
170 OS <<
"Deleting an array of '" << TargetType.
getAsString()
171 <<
"' objects as their base class '"
172 << SourceType.
getAsString(
C.getASTContext().getPrintingPolicy())
175 auto R = std::make_unique<PathSensitiveBugReport>(BT, OS.str(), N);
178 R->markInteresting(BaseClassRegion);
179 R->addVisitor<PtrCastVisitor>();
180 C.emitReport(std::move(R));
184CXXDeleteChecker::PtrCastVisitor::VisitNode(
const ExplodedNode *N,
191 const auto *CastE = dyn_cast<CastExpr>(S);
199 if (SourceType.
isNull() || TargetType.
isNull() || SourceType == TargetType)
212 llvm::raw_svector_ostream OS(Buf);
214 OS <<
"Casting from '" << SourceType.
getAsString() <<
"' to '"
219 return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(),
227bool ento::shouldRegisterArrayDeleteChecker(
const CheckerManager &mgr) {
231void ento::registerDeleteWithNonVirtualDtorChecker(
CheckerManager &mgr) {
235bool ento::shouldRegisterDeleteWithNonVirtualDtorChecker(
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
This represents one expression.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Stmt - This represents one statement.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
const Stmt * getStmtForDiagnostics() const
If the node's program point corresponds to a statement, retrieve that statement.
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
const LocationContext * getLocationContext() const
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
const RegionTy * getAs() const
bool isInteresting(SymbolRef sym) const
const MemRegion * getAsRegion() const
virtual QualType getType() const =0
SymbolicRegion - A special, "non-concrete" region.
SymbolRef getSymbol() const
It might return null.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.