10class UseAfterLifetimeEnd :
public Checker<check::EndFunction> {
12 void reportDanglingSource(
const MemRegion *Source, SVal Val, ExplodedNode *N,
13 CheckerContext &
C)
const;
14 void checkEndFunction(
const ReturnStmt *RS, CheckerContext &
C)
const;
15 const BugType BugMsg{
this,
"UseAfterLifetimeEnd",
"LifetimeBound"};
20 const MemRegion *SourceRegion;
23 explicit UseAfterLifetimeEndBRVisitor(SVal Val,
const MemRegion *Source)
24 : BoundVal(Val), SourceRegion(Source) {}
26 void Profile(llvm::FoldingSetNodeID &ID)
const override {
30 SourceRegion->Profile(ID);
34 BugReporterContext &BRC,
35 PathSensitiveBugReport &BR)
override;
37 BugReporterContext &BRC,
38 PathSensitiveBugReport &BR)
override;
40 BugReporterContext &BRC,
41 StringRef Message)
const;
47 const CallExpr *
Expr = dyn_cast_or_null<CallExpr>(RetExpr);
55 if (PVD->hasAttr<LifetimeBoundAttr>()) {
56 unsigned Idx = PVD->getFunctionScopeIndex();
57 if (Idx < Expr->getNumArgs())
58 return Expr->getArg(Idx);
64void UseAfterLifetimeEnd::checkEndFunction(
const ReturnStmt *RS,
76 SVal RetVal =
C.getSVal(RetExpr);
78 std::vector<const MemRegion *> RetValRegion =
80 if (RetValRegion.empty())
84 C.generateNonFatalErrorNode(State,
C.getPredecessor())) {
85 for (
const MemRegion *R : RetValRegion)
86 reportDanglingSource(R, RetVal, N,
C);
91 if (
const auto *VR = dyn_cast_or_null<VarRegion>(Source))
92 return VR->getDecl()->getSourceRange();
96void UseAfterLifetimeEnd::reportDanglingSource(
const MemRegion *Source,
97 SVal RetVal, ExplodedNode *N,
98 CheckerContext &
C)
const {
99 auto BR = std::make_unique<PathSensitiveBugReport>(
101 (llvm::Twine(
"Returning value bound to ") +
108 BR->addVisitor<UseAfterLifetimeEndBRVisitor>(RetVal, Source);
110 C.emitReport(std::move(BR));
114 const ExplodedNode *N, BugReporterContext &BRC, StringRef Message)
const {
119 const Expr *RetExpr = dyn_cast_or_null<Expr>(S);
122 PathDiagnosticLocation Pos;
127 auto Note = std::make_shared<PathDiagnosticEventPiece>(Pos, Message,
true);
129 Note->addRange(Range);
135UseAfterLifetimeEndBRVisitor::VisitNode(
const ExplodedNode *N,
136 BugReporterContext &BRC,
137 PathSensitiveBugReport &BR) {
146 auto Piece = createSourcePiece(
148 (llvm::Twine(
"Value's lifetime bound to the lifetime of ") +
155UseAfterLifetimeEndBRVisitor::getEndPath(
const ExplodedNode *N,
156 BugReporterContext &BRC,
157 PathSensitiveBugReport &BR) {
158 auto Piece = createSourcePiece(
160 (llvm::Twine(
"Lifetime of ") +
166void ento::registerUseAfterLifetimeEnd(CheckerManager &Mgr) {
170bool ento::shouldRegisterUseAfterLifetimeEnd(
const CheckerManager &Mgr) {
static SourceRange getRegionDeclRange(const MemRegion *Source)
static const Expr * getLifetimeBoundArg(const Expr *RetExpr)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a function declaration or definition.
ArrayRef< ParmVarDecl * > parameters() const
Represents a parameter to a function.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
A trivial tuple used to represent a source range.
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
MemRegion - The root abstract class for all memory regions.
void trackStoredValue(SVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts={}, const StackFrame *Origin=nullptr)
Track how the value got stored into the given region and where it came from.
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 isBoundToLifetimeSource(ProgramStateRef State, SVal Val)
Returns true if Val is a key in the LifetimeBoundMap.
std::vector< const MemRegion * > getDanglingRegionsAfterReturn(SVal Source, ProgramStateRef State, CheckerContext &C)
Returns the set of lifetime sources bound to Source that are dangling stack regions.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.