13class DanglingPtrDeref :
public Checker<check::Location, check::PostCall> {
15 void checkLocation(SVal Loc,
bool IsLoad,
const Stmt *S,
16 CheckerContext &
C)
const;
17 void checkPostCall(
const CallEvent &
Call, CheckerContext &
C)
const;
18 void reportUseAfterScope(
const MemRegion *Region,
const Stmt *S,
19 ExplodedNode *N, CheckerContext &
C)
const;
20 const BugType BugMsg{
this,
"ReportDanglingPtrDeref",
"LifetimeBound"};
24 const MemRegion *SourceRegion;
27 explicit DanglingPtrDerefBRVisitor(
const MemRegion *Source)
28 : SourceRegion(Source) {}
30 void Profile(llvm::FoldingSetNodeID &ID)
const override {
31 ID.AddPointer(SourceRegion);
35 BugReporterContext &BRC,
36 PathSensitiveBugReport &BR)
override;
41void DanglingPtrDeref::checkLocation(
SVal Loc,
bool IsLoad,
const Stmt *S,
45 if (
const MemRegion *LocRegion = Loc.
getAsRegion()) {
47 if (ExplodedNode *N =
C.generateNonFatalErrorNode(State))
48 reportUseAfterScope(LocRegion, S, N,
C);
53void DanglingPtrDeref::checkPostCall(
const CallEvent &
Call,
54 CheckerContext &
C)
const {
61 for (
unsigned Idx = 0; Idx <
Call.getNumArgs(); Idx++) {
62 if (
const MemRegion *ArgRegion =
Call.getArgSVal(Idx).getAsRegion())
64 if (ExplodedNode *N =
C.generateNonFatalErrorNode())
65 reportUseAfterScope(ArgRegion,
Call.getArgExpr(Idx), N,
C);
69void DanglingPtrDeref::reportUseAfterScope(
const MemRegion *Region,
70 const Stmt *S, ExplodedNode *N,
71 CheckerContext &
C)
const {
72 auto BR = std::make_unique<PathSensitiveBugReport>(
75 " after its lifetime ended."),
77 BR->addVisitor<DanglingPtrDerefBRVisitor>(Region);
82 C.emitReport(std::move(BR));
86DanglingPtrDerefBRVisitor::VisitNode(
const ExplodedNode *N,
87 BugReporterContext &BRC,
88 PathSensitiveBugReport &BR) {
104 return std::make_shared<PathDiagnosticEventPiece>(
107 llvm::Twine(
" is destroyed here"))
112void ento::registerDanglingPtrDeref(CheckerManager &Mgr) {
116bool ento::shouldRegisterDanglingPtrDeref(
const CheckerManager &Mgr) {
Stmt - This represents one statement.
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
const ProgramStateRef & getState() const
const Stmt * getStmtForDiagnostics() const
If the node's program point corresponds to a statement, retrieve that statement.
ExplodedNode * getFirstPred()
const StackFrame * getStackFrame() const
static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const StackFrameOrAnalysisDeclContext SFAC)
Create a location for the end of the statement.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
const Expr * getDerefExpr(const Stmt *S)
Given that expression S represents a pointer that would be dereferenced, try to find a sub-expression...
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
std::string getRegionName(const MemRegion *Reg)
Returns the descriptive name of the memory region or a placeholder if a descriptive name cannot be co...
bool isDeallocated(ProgramStateRef State, const MemRegion *Region)
Returns true if the underlying MemRegion is deallocated.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.