19
19
#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
20
20
#include " clang/Analysis/AnalysisDeclContext.h"
21
21
#include " clang/Analysis/CFG.h"
22
+ #include " clang/Basic/SourceLocation.h"
23
+ #include " llvm/ADT/DenseMapInfo.h"
24
+ #include " llvm/ADT/ImmutableMap.h"
22
25
#include " llvm/ADT/ImmutableSet.h"
23
26
#include " llvm/ADT/StringMap.h"
24
27
#include < memory>
25
28
26
29
namespace clang ::lifetimes {
27
30
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
+
28
48
// / The main entry point for the analysis.
29
- void runLifetimeSafetyAnalysis (AnalysisDeclContext &AC);
49
+ void runLifetimeSafetyAnalysis (AnalysisDeclContext &AC,
50
+ LifetimeSafetyReporter *Reporter);
30
51
31
52
namespace internal {
32
53
// Forward declarations of internal types.
@@ -53,6 +74,7 @@ template <typename Tag> struct ID {
53
74
IDBuilder.AddInteger (Value);
54
75
}
55
76
};
77
+
56
78
template <typename Tag>
57
79
inline llvm::raw_ostream &operator <<(llvm::raw_ostream &OS, ID<Tag> ID) {
58
80
return OS << ID.Value ;
@@ -66,6 +88,7 @@ using OriginID = ID<struct OriginTag>;
66
88
// TODO(opt): Consider using a bitset to represent the set of loans.
67
89
using LoanSet = llvm::ImmutableSet<LoanID>;
68
90
using OriginSet = llvm::ImmutableSet<OriginID>;
91
+ using ExpiredLoanMap = llvm::ImmutableMap<LoanID, const Fact *>;
69
92
70
93
// / A `ProgramPoint` identifies a location in the CFG by pointing to a specific
71
94
// / `Fact`. identified by a lifetime-related event (`Fact`).
@@ -78,7 +101,8 @@ using ProgramPoint = const Fact *;
78
101
// / encapsulates the various dataflow analyses.
79
102
class LifetimeSafetyAnalysis {
80
103
public:
81
- LifetimeSafetyAnalysis (AnalysisDeclContext &AC);
104
+ LifetimeSafetyAnalysis (AnalysisDeclContext &AC,
105
+ LifetimeSafetyReporter *Reporter);
82
106
~LifetimeSafetyAnalysis ();
83
107
84
108
void run ();
@@ -87,7 +111,7 @@ class LifetimeSafetyAnalysis {
87
111
LoanSet getLoansAtPoint (OriginID OID, ProgramPoint PP) const ;
88
112
89
113
// / 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 ;
91
115
92
116
// / Finds the OriginID for a given declaration.
93
117
// / Returns a null optional if not found.
@@ -110,6 +134,7 @@ class LifetimeSafetyAnalysis {
110
134
111
135
private:
112
136
AnalysisDeclContext &AC;
137
+ LifetimeSafetyReporter *Reporter;
113
138
std::unique_ptr<LifetimeFactory> Factory;
114
139
std::unique_ptr<FactManager> FactMgr;
115
140
std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
@@ -118,4 +143,25 @@ class LifetimeSafetyAnalysis {
118
143
} // namespace internal
119
144
} // namespace clang::lifetimes
120
145
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
+
121
167
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
0 commit comments