Skip to content

Commit 2ff9adf

Browse files
committed
[LifetimeSafety] Revamp test suite using unittests
1 parent d9190f8 commit 2ff9adf

File tree

5 files changed

+415
-59
lines changed

5 files changed

+415
-59
lines changed

clang/include/clang/Analysis/Analyses/LifetimeSafety.h

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,80 @@
2020
#include "clang/AST/DeclBase.h"
2121
#include "clang/Analysis/AnalysisDeclContext.h"
2222
#include "clang/Analysis/CFG.h"
23-
namespace clang {
23+
#include "llvm/ADT/ImmutableSet.h"
24+
#include "llvm/ADT/StringMap.h"
25+
#include <memory>
2426

25-
void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
26-
AnalysisDeclContext &AC);
27+
namespace clang::lifetimes {
28+
namespace internal {
29+
// Forward declarations of internal types.
30+
class Fact;
31+
class FactManager;
32+
class LoanPropagationAnalysis;
33+
struct LifetimeFactory;
2734

28-
} // namespace clang
35+
/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
36+
/// Used for giving ID to loans and origins.
37+
template <typename Tag> struct ID {
38+
uint32_t Value = 0;
39+
40+
bool operator==(const ID<Tag> &Other) const { return Value == Other.Value; }
41+
bool operator!=(const ID<Tag> &Other) const { return !(*this == Other); }
42+
bool operator<(const ID<Tag> &Other) const { return Value < Other.Value; }
43+
ID<Tag> operator++(int) {
44+
ID<Tag> Tmp = *this;
45+
++Value;
46+
return Tmp;
47+
}
48+
void Profile(llvm::FoldingSetNodeID &IDBuilder) const {
49+
IDBuilder.AddInteger(Value);
50+
}
51+
};
52+
53+
using LoanID = ID<struct LoanTag>;
54+
using OriginID = ID<struct OriginTag>;
55+
56+
// Using LLVM's immutable collections is efficient for dataflow analysis
57+
// as it avoids deep copies during state transitions.
58+
// TODO(opt): Consider using a bitset to represent the set of loans.
59+
using LoanSet = llvm::ImmutableSet<LoanID>;
60+
using OriginSet = llvm::ImmutableSet<OriginID>;
61+
62+
using ProgramPoint = std::pair<const CFGBlock *, const Fact *>;
63+
64+
/// Running the lifetime safety analysis and querying its results. It
65+
/// encapsulates the various dataflow analyses.
66+
class LifetimeSafetyAnalysis {
67+
public:
68+
LifetimeSafetyAnalysis(AnalysisDeclContext &AC);
69+
~LifetimeSafetyAnalysis();
70+
71+
void run();
72+
73+
/// Returns the set of loans an origin holds at a specific program point.
74+
LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
75+
76+
/// Finds the OriginID for a given declaration.
77+
/// Returns a null optional if not found.
78+
std::optional<OriginID> getOriginIDForDecl(const ValueDecl *D) const;
79+
80+
/// Finds the LoanID for a loan created on a specific variable.
81+
/// Returns a null optional if not found.
82+
std::optional<LoanID> getLoanIDForVar(const VarDecl *VD) const;
83+
84+
llvm::StringMap<ProgramPoint> getTestPoints() const;
85+
86+
private:
87+
AnalysisDeclContext &AC;
88+
std::unique_ptr<LifetimeFactory> Factory;
89+
std::unique_ptr<FactManager> FactMgr;
90+
std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
91+
};
92+
} // namespace internal
93+
94+
/// The main entry point for the analysis.
95+
void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC);
96+
97+
} // namespace clang::lifetimes
2998

3099
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H

0 commit comments

Comments
 (0)