23#include "llvm/ADT/DenseMap.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/TimeProfiler.h"
38 llvm_unreachable(
"unknown liveness kind");
44struct PendingWarning {
46 llvm::PointerUnion<const UseFact *, const OriginEscapesFact *> CausingFact;
50class LifetimeChecker {
52 llvm::DenseMap<LoanID, PendingWarning> FinalWarningsMap;
53 const LoanPropagationAnalysis &LoanPropagation;
54 const LiveOriginsAnalysis &LiveOrigins;
55 const FactManager &FactMgr;
56 LifetimeSafetyReporter *Reporter;
59 LifetimeChecker(
const LoanPropagationAnalysis &LoanPropagation,
60 const LiveOriginsAnalysis &LiveOrigins,
const FactManager &FM,
62 : LoanPropagation(LoanPropagation), LiveOrigins(LiveOrigins), FactMgr(FM),
65 for (
const Fact *F : FactMgr.getFacts(B))
66 if (
const auto *EF = F->getAs<ExpireFact>())
68 issuePendingWarnings();
82 void checkExpiry(
const ExpireFact *EF) {
83 LoanID ExpiredLoan = EF->getLoanID();
84 LivenessMap Origins = LiveOrigins.getLiveOriginsAt(EF);
88 llvm::PointerUnion<const UseFact *, const OriginEscapesFact *>
89 BestCausingFact =
nullptr;
91 for (
auto &[OID, LiveInfo] : Origins) {
92 LoanSet HeldLoans = LoanPropagation.getLoans(OID, EF);
93 if (!HeldLoans.contains(ExpiredLoan))
97 if (CurConfidence < NewConfidence) {
98 CurConfidence = NewConfidence;
99 BestCausingFact = LiveInfo.CausingFact;
102 if (!BestCausingFact)
105 Confidence LastConf = FinalWarningsMap.lookup(ExpiredLoan).ConfidenceLevel;
106 if (LastConf >= CurConfidence)
108 FinalWarningsMap[ExpiredLoan] = {EF->getExpiryLoc(),
113 void issuePendingWarnings() {
116 for (
const auto &[LID,
Warning] : FinalWarningsMap) {
117 const Loan &L = FactMgr.getLoanMgr().getLoan(LID);
118 const Expr *IssueExpr = L.IssueExpr;
119 llvm::PointerUnion<const UseFact *, const OriginEscapesFact *>
120 CausingFact =
Warning.CausingFact;
122 SourceLocation ExpiryLoc =
Warning.ExpiryLoc;
124 if (
const auto *UF = CausingFact.dyn_cast<
const UseFact *>())
125 Reporter->reportUseAfterFree(IssueExpr, UF->getUseExpr(), ExpiryLoc,
127 else if (
const auto *OEF =
128 CausingFact.dyn_cast<
const OriginEscapesFact *>())
129 Reporter->reportUseAfterReturn(IssueExpr, OEF->getEscapeExpr(),
132 llvm_unreachable(
"Unhandled CausingFact type");
142 llvm::TimeTraceScope TimeProfile(
"LifetimeChecker");
143 LifetimeChecker Checker(LP, LO, FactMgr, ADC, Reporter);
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Defines the clang::SourceLocation class and associated facilities.
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a single basic block in a source-level CFG.
Encodes a location in the source.
llvm::ImmutableSet< LoanID > LoanSet
utils::ID< struct LoanTag > LoanID
llvm::ImmutableMap< OriginID, LivenessInfo > LivenessMap
void runLifetimeChecker(const LoanPropagationAnalysis &LoanPropagation, const LiveOriginsAnalysis &LiveOrigins, const FactManager &FactMgr, AnalysisDeclContext &ADC, LifetimeSafetyReporter *Reporter)
Runs the lifetime checker, which detects use-after-free errors by examining loan expiration points an...
static Confidence livenessKindToConfidence(LivenessKind K)
Confidence
Enum to track the confidence level of a potential error.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
for(const auto &A :T->param_types())