1919#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
2020#include " clang/Analysis/AnalysisDeclContext.h"
2121#include " clang/Analysis/CFG.h"
22+ #include " clang/Basic/SourceLocation.h"
23+ #include " llvm/ADT/DenseMapInfo.h"
24+ #include " llvm/ADT/ImmutableMap.h"
2225#include " llvm/ADT/ImmutableSet.h"
2326#include " llvm/ADT/StringMap.h"
2427#include < memory>
2528
2629namespace clang ::lifetimes {
2730
31+ // / Enum to track the confidence level of a potential error.
32+ enum class Confidence {
33+ None,
34+ Maybe, // Reported as a potential error (-Wlifetime-safety-strict)
35+ Definite // Reported as a definite error (-Wlifetime-safety-permissive)
36+ };
37+
38+ class LifetimeSafetyReporter {
39+ public:
40+ LifetimeSafetyReporter () = default ;
41+ virtual ~LifetimeSafetyReporter () = default ;
42+
43+ virtual void reportUseAfterFree (const Expr *IssueExpr, const Expr *UseExpr,
44+ SourceLocation FreeLoc,
45+ Confidence Confidence) {}
46+ };
47+
2848// / The main entry point for the analysis.
29- void runLifetimeSafetyAnalysis (AnalysisDeclContext &AC);
49+ void runLifetimeSafetyAnalysis (AnalysisDeclContext &AC,
50+ LifetimeSafetyReporter *Reporter);
3051
3152namespace internal {
3253// Forward declarations of internal types.
@@ -53,6 +74,7 @@ template <typename Tag> struct ID {
5374 IDBuilder.AddInteger (Value);
5475 }
5576};
77+
5678template <typename Tag>
5779inline llvm::raw_ostream &operator <<(llvm::raw_ostream &OS, ID<Tag> ID) {
5880 return OS << ID.Value ;
@@ -66,6 +88,7 @@ using OriginID = ID<struct OriginTag>;
6688// TODO(opt): Consider using a bitset to represent the set of loans.
6789using LoanSet = llvm::ImmutableSet<LoanID>;
6890using OriginSet = llvm::ImmutableSet<OriginID>;
91+ using ExpiredLoanMap = llvm::ImmutableMap<LoanID, const Fact *>;
6992
7093// / A `ProgramPoint` identifies a location in the CFG by pointing to a specific
7194// / `Fact`. identified by a lifetime-related event (`Fact`).
@@ -78,7 +101,8 @@ using ProgramPoint = const Fact *;
78101// / encapsulates the various dataflow analyses.
79102class LifetimeSafetyAnalysis {
80103public:
81- LifetimeSafetyAnalysis (AnalysisDeclContext &AC);
104+ LifetimeSafetyAnalysis (AnalysisDeclContext &AC,
105+ LifetimeSafetyReporter *Reporter);
82106 ~LifetimeSafetyAnalysis ();
83107
84108 void run ();
@@ -87,7 +111,7 @@ class LifetimeSafetyAnalysis {
87111 LoanSet getLoansAtPoint (OriginID OID, ProgramPoint PP) const ;
88112
89113 // / Returns the set of loans that have expired at a specific program point.
90- LoanSet getExpiredLoansAtPoint (ProgramPoint PP) const ;
114+ ExpiredLoanMap getExpiredLoansAtPoint (ProgramPoint PP) const ;
91115
92116 // / Finds the OriginID for a given declaration.
93117 // / Returns a null optional if not found.
@@ -110,6 +134,7 @@ class LifetimeSafetyAnalysis {
110134
111135private:
112136 AnalysisDeclContext &AC;
137+ LifetimeSafetyReporter *Reporter;
113138 std::unique_ptr<LifetimeFactory> Factory;
114139 std::unique_ptr<FactManager> FactMgr;
115140 std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
@@ -118,4 +143,25 @@ class LifetimeSafetyAnalysis {
118143} // namespace internal
119144} // namespace clang::lifetimes
120145
146+ namespace llvm {
147+ template <typename Tag>
148+ struct DenseMapInfo <clang::lifetimes::internal::ID<Tag>> {
149+ using ID = clang::lifetimes::internal::ID<Tag>;
150+
151+ static inline ID getEmptyKey () {
152+ return {DenseMapInfo<uint32_t >::getEmptyKey ()};
153+ }
154+
155+ static inline ID getTombstoneKey () {
156+ return {DenseMapInfo<uint32_t >::getTombstoneKey ()};
157+ }
158+
159+ static unsigned getHashValue (const ID &Val) {
160+ return DenseMapInfo<uint32_t >::getHashValue (Val.Value );
161+ }
162+
163+ static bool isEqual (const ID &LHS, const ID &RHS) { return LHS == RHS; }
164+ };
165+ } // namespace llvm
166+
121167#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
0 commit comments