34 using namespace clang;
38 class DeleteWithNonVirtualDtorChecker
39 :
public Checker<check::PreStmt<CXXDeleteExpr>> {
40 mutable std::unique_ptr<BugType> BT;
44 DeleteBugVisitor() : Satisfied(
false) {}
45 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
49 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
63 void DeleteWithNonVirtualDtorChecker::checkPreStmt(
const CXXDeleteExpr *DE,
72 if (!BaseClassRegion || !DerivedClassRegion)
75 const auto *BaseClass = BaseClassRegion->getValueType()->getAsCXXRecordDecl();
76 const auto *DerivedClass =
77 DerivedClassRegion->getSymbol()->getType()->getPointeeCXXRecordDecl();
78 if (!BaseClass || !DerivedClass)
81 if (!BaseClass->hasDefinition() || !DerivedClass->hasDefinition())
84 if (BaseClass->getDestructor()->isVirtual())
87 if (!DerivedClass->isDerivedFrom(BaseClass))
92 "Destruction of a polymorphic object with no " 97 auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
100 R->markInteresting(BaseClassRegion);
101 R->addVisitor(llvm::make_unique<DeleteBugVisitor>());
105 std::shared_ptr<PathDiagnosticPiece>
106 DeleteWithNonVirtualDtorChecker::DeleteBugVisitor::VisitNode(
117 const auto *CastE = dyn_cast<
CastExpr>(S);
123 if (
const auto *ImplCastE = dyn_cast<ImplicitCastExpr>(CastE)) {
124 if (ImplCastE->getCastKind() != CK_DerivedToBase)
141 llvm::raw_svector_ostream OS(Buf);
142 OS <<
"Conversion from derived to base happened here";
145 return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(),
true,
149 void ento::registerDeleteWithNonVirtualDtorChecker(
CheckerManager &mgr) {
TypedValueRegion - An abstract class representing regions having a typed value.
MemRegion - The root abstract class for all memory regions.
bool isInteresting(SymbolRef sym)
Stmt - This represents one statement.
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
const LocationContext * getLocationContext() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const RegionTy * getAs() const
SymbolicRegion - A special, "non-concrete" region.
Expr - This represents one expression.
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
CHECKER * registerChecker(AT... Args)
Used to register checkers.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
const MemRegion * getAsRegion() const
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
Dataflow Directional Tag Classes.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
const MemRegion * getBaseRegion() const
This class provides an interface through which checkers can create individual bug reports...
SourceManager & getSourceManager()