clang 23.0.0git
Loans.h
Go to the documentation of this file.
1//===- Loans.h - Loan and Access Path Definitions --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the Loan and AccessPath structures, which represent
10// borrows of storage locations, and the LoanManager, which manages the
11// creation and retrieval of loans during lifetime analysis.
12//
13//===----------------------------------------------------------------------===//
14#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
15#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
16
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/ExprCXX.h"
21#include "llvm/Support/raw_ostream.h"
22
24
26inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, LoanID ID) {
27 return OS << ID.Value;
28}
29
30/// Represents the storage location being borrowed, e.g., a specific stack
31/// variable.
32/// TODO: Model access paths of other types, e.g., s.field, heap and globals.
34 // An access path can be:
35 // - ValueDecl * , to represent the storage location corresponding to the
36 // variable declared in ValueDecl.
37 // - MaterializeTemporaryExpr * , to represent the storage location of the
38 // temporary object materialized via this MaterializeTemporaryExpr.
39 const llvm::PointerUnion<const clang::ValueDecl *,
41 P;
42
43public:
44 AccessPath(const clang::ValueDecl *D) : P(D) {}
46
48 return P.dyn_cast<const clang::ValueDecl *>();
49 }
50
54
55 bool operator==(const AccessPath &RHS) const { return P == RHS.P; }
56};
57
58/// An abstract base class for a single "Loan" which represents lending a
59/// storage in memory.
60class Loan {
61 /// TODO: Represent opaque loans.
62 /// TODO: Represent nullptr: loans to no path. Accessing it UB! Currently it
63 /// is represented as empty LoanSet
64public:
65 enum class Kind : uint8_t {
66 /// A loan with an access path to a storage location.
68 /// A non-expiring placeholder loan for a parameter, representing a borrow
69 /// from the function's caller.
71 };
72
73 Loan(Kind K, LoanID ID) : K(K), ID(ID) {}
74 virtual ~Loan() = default;
75
76 Kind getKind() const { return K; }
77 LoanID getID() const { return ID; }
78
79 virtual void dump(llvm::raw_ostream &OS) const = 0;
80
81private:
82 const Kind K;
83 const LoanID ID;
84};
85
86/// PathLoan represents lending a storage location that is visible within the
87/// function's scope (e.g., a local variable on stack).
88class PathLoan : public Loan {
89 AccessPath Path;
90 /// The expression that creates the loan, e.g., &x.
91 const Expr *IssueExpr;
92
93public:
94 PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr)
95 : Loan(Kind::Path, ID), Path(Path), IssueExpr(IssueExpr) {}
96
97 const AccessPath &getAccessPath() const { return Path; }
98 const Expr *getIssueExpr() const { return IssueExpr; }
99
100 void dump(llvm::raw_ostream &OS) const override;
101
102 static bool classof(const Loan *L) { return L->getKind() == Kind::Path; }
103};
104
105/// A placeholder loan held by a function parameter or an implicit 'this'
106/// object, representing a borrow from the caller's scope.
107///
108/// Created at function entry for each pointer or reference parameter or for
109/// the implicit 'this' parameter of instance methods, with an
110/// origin. Unlike PathLoan, placeholder loans:
111/// - Have no IssueExpr (created at function entry, not at a borrow site)
112/// - Have no AccessPath (the borrowed object is not visible to the function)
113/// - Do not currently expire, but may in the future when modeling function
114/// invalidations (e.g., vector::push_back)
115///
116/// When a placeholder loan escapes the function (e.g., via return), it
117/// indicates the parameter or method should be marked [[clang::lifetimebound]],
118/// enabling lifetime annotation suggestions.
119class PlaceholderLoan : public Loan {
120 /// The function parameter or method (representing 'this') that holds this
121 /// placeholder loan.
122 llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *> ParamOrMethod;
123
124public:
126 : Loan(Kind::Placeholder, ID), ParamOrMethod(PVD) {}
127
129 : Loan(Kind::Placeholder, ID), ParamOrMethod(MD) {}
130
132 return ParamOrMethod.dyn_cast<const ParmVarDecl *>();
133 }
134
136 return ParamOrMethod.dyn_cast<const CXXMethodDecl *>();
137 }
138
139 void dump(llvm::raw_ostream &OS) const override;
140
141 static bool classof(const Loan *L) {
142 return L->getKind() == Kind::Placeholder;
143 }
144};
145
146/// Manages the creation, storage and retrieval of loans.
148public:
149 LoanManager() = default;
150
151 template <typename LoanType, typename... Args>
152 LoanType *createLoan(Args &&...args) {
153 static_assert(
154 std::is_same_v<LoanType, PathLoan> ||
155 std::is_same_v<LoanType, PlaceholderLoan>,
156 "createLoan can only be used with PathLoan or PlaceholderLoan");
157 void *Mem = LoanAllocator.Allocate<LoanType>();
158 auto *NewLoan =
159 new (Mem) LoanType(getNextLoanID(), std::forward<Args>(args)...);
160 AllLoans.push_back(NewLoan);
161 return NewLoan;
162 }
163
164 const Loan *getLoan(LoanID ID) const {
165 assert(ID.Value < AllLoans.size());
166 return AllLoans[ID.Value];
167 }
168 llvm::ArrayRef<const Loan *> getLoans() const { return AllLoans; }
169
170private:
171 LoanID getNextLoanID() { return NextLoanID++; }
172
173 LoanID NextLoanID{0};
174 /// TODO(opt): Profile and evaluate the usefullness of small buffer
175 /// optimisation.
177 llvm::BumpPtrAllocator LoanAllocator;
178};
179} // namespace clang::lifetimes::internal
180
181#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
This represents one expression.
Definition Expr.h:112
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4921
Represents a parameter to a function.
Definition Decl.h:1790
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Represents the storage location being borrowed, e.g., a specific stack variable.
Definition Loans.h:33
AccessPath(const clang::ValueDecl *D)
Definition Loans.h:44
const clang::ValueDecl * getAsValueDecl() const
Definition Loans.h:47
bool operator==(const AccessPath &RHS) const
Definition Loans.h:55
AccessPath(const clang::MaterializeTemporaryExpr *MTE)
Definition Loans.h:45
const clang::MaterializeTemporaryExpr * getAsMaterializeTemporaryExpr() const
Definition Loans.h:51
llvm::ArrayRef< const Loan * > getLoans() const
Definition Loans.h:168
const Loan * getLoan(LoanID ID) const
Definition Loans.h:164
LoanType * createLoan(Args &&...args)
Definition Loans.h:152
An abstract base class for a single "Loan" which represents lending a storage in memory.
Definition Loans.h:60
Loan(Kind K, LoanID ID)
Definition Loans.h:73
Kind
TODO: Represent opaque loans.
Definition Loans.h:65
@ Placeholder
A non-expiring placeholder loan for a parameter, representing a borrow from the function's caller.
Definition Loans.h:70
@ Path
A loan with an access path to a storage location.
Definition Loans.h:67
virtual void dump(llvm::raw_ostream &OS) const =0
const Expr * getIssueExpr() const
Definition Loans.h:98
PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr)
Definition Loans.h:94
const AccessPath & getAccessPath() const
Definition Loans.h:97
static bool classof(const Loan *L)
Definition Loans.h:102
void dump(llvm::raw_ostream &OS) const override
Definition Loans.cpp:13
PlaceholderLoan(LoanID ID, const CXXMethodDecl *MD)
Definition Loans.h:128
void dump(llvm::raw_ostream &OS) const override
Definition Loans.cpp:26
static bool classof(const Loan *L)
Definition Loans.h:141
PlaceholderLoan(LoanID ID, const ParmVarDecl *PVD)
Definition Loans.h:125
const CXXMethodDecl * getMethodDecl() const
Definition Loans.h:135
const ParmVarDecl * getParmVarDecl() const
Definition Loans.h:131
utils::ID< struct LoanTag > LoanID
Definition Loans.h:25
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, LoanID ID)
Definition Loans.h:26
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21