19#include "llvm/ADT/STLExtras.h"
27 std::optional<bool> isUnsafeType(QualType QT)
const override {
30 std::optional<bool> isUnsafePtr(QualType QT,
bool)
const override {
36 bool isSafePtrType(QualType
T)
const override {
39 bool isPtrType(
const std::string &Name)
const override {
42 const char *typeName()
const override {
return "RefPtr-capable type"; }
47 std::optional<bool> isUnsafeType(QualType QT)
const override {
50 std::optional<bool> isUnsafePtr(QualType QT,
bool)
const override {
56 bool isSafePtrType(QualType
T)
const override {
59 bool isPtrType(
const std::string &Name)
const override {
62 bool isSafeExpr(
const Expr *E,
bool, QualType,
bool)
const override {
65 const char *typeName()
const override {
return "CheckedPtr-capable type"; }
69 mutable RetainTypeChecker RTC;
72 std::optional<bool> isUnsafeType(QualType QT)
const override {
73 return RTC.isUnretained(QT);
75 std::optional<bool> isUnsafePtr(QualType QT,
bool IgnoreARC)
const override {
76 return RTC.isUnretained(QT, IgnoreARC);
81 bool isSafePtrType(QualType
T)
const override {
84 bool isPtrType(
const std::string &Name)
const override {
87 bool isSafeExpr(
const Expr *E,
bool, QualType,
bool)
const override {
91 bool isSafeDecl(
const Decl *D,
const SourceManager &SM)
const override {
95 void describeHazard(llvm::raw_ostream &Os,
const Expr *Origin,
96 QualType SinkType)
const override {
99 Os << typeName() <<
" ";
100 if (
auto *Decl = RTC.getCanonicalDecl(SinkType)) {
103 const auto *
Typedef = VarType->getAs<TypedefType>();
111 const char *typeName()
const override {
return "RetainPtr-capable type"; }
112 RetainTypeChecker *retainTypeChecker()
const override {
return &RTC; }
115static std::optional<bool> isCanBorrowType(
QualType T) {
116 auto *
Record =
T->getAsCXXRecordDecl();
125 return RecordA && RecordB &&
131 if (
auto *DeclRef = dyn_cast<DeclRefExpr>(Stripped))
132 return DeclRef->getDecl();
133 if (
auto *
Member = dyn_cast<MemberExpr>(Stripped))
134 return Member->getMemberDecl();
143 if (
auto *Op = dyn_cast<CXXOperatorCallExpr>(Stripped)) {
145 if ((Kind != OO_Star && Kind != OO_Arrow) || Op->getNumArgs() != 1)
149 return constDeclaredObject(Op->getArg(0));
153 if (!isa_and_nonnull<VarDecl>(
Decl) && !isa_and_nonnull<FieldDecl>(
Decl))
156 if (!
T.isConstQualified() ||
T->isReferenceType() ||
T->isPointerType())
166 return isSameRecord(Pointee, CanBorrowType);
172 return isSameRecord(
borrowedType(ViewType), CanBorrowType);
177 return llvm::any_of(
Record->fields(),
179 return mayHoldPointerTo(Field->getType(),
183 return mayHoldPointerTo(Base.getType(), CanBorrowType);
189 std::optional<bool> isUnsafeType(QualType QT)
const override {
192 std::optional<bool> isUnsafePtr(QualType QT,
bool)
const override {
198 bool isSafePtrType(QualType
T)
const override {
return isBorrowType(
T); }
199 bool isPtrType(
const std::string &Name)
const override {
203 bool isSafeExpr(
const Expr *Origin,
bool PtrIsLifetimeBoundToOrigin,
204 QualType SinkType,
bool SinkMayEscape)
const override {
213 return !SinkMayEscape;
215 if (!PtrIsLifetimeBoundToOrigin)
218 if (
const ValueDecl *ConstObject = constDeclaredObject(Origin)) {
219 auto *ConstVar = dyn_cast<VarDecl>(ConstObject);
220 if (!SinkMayEscape || (ConstVar && ConstVar->hasGlobalStorage()))
225 isCanBorrowType(Origin->
getType()).value_or(
false) &&
226 !SinkType.
isNull() && !mayHoldPointerTo(SinkType, Origin->
getType()))
234 return !Borrowable || !*Borrowable;
237 bool checksForInteriorDestruction()
const override {
return true; }
238 bool recognizesIndirectStores()
const override {
return true; }
239 const char *typeName()
const override {
return "CanBorrow type"; }
241 void describeHazard(llvm::raw_ostream &Os,
const Expr *Origin,
242 QualType SinkType)
const override {
245 Os <<
"Borrow that does not travel with the lambda";
258 Os <<
"CanBorrow type ";
259 printTypeName(Os, OriginType);
261 Os <<
"a CanBorrow object";
262 Os <<
" that is not guarded by const or a Borrow";
273 if (Model.retainTypeChecker() &&
T.hasStrongOrWeakObjCLifetime())
275 return Model.isUnsafePtr(
T, IgnoreARC);
279 return std::make_unique<RefCountedSafetyModel>();
283 return std::make_unique<CheckedPtrSafetyModel>();
287 return std::make_unique<RetainPtrSafetyModel>();
291 return std::make_unique<BorrowSafetyModel>();
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Record Record
Defines the SourceManager interface.
C Language Family Type Representation.
Represents a base class of a C++ class.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
This represents one expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Represents a member of a struct/union/class.
Models one WebKit pointer-safety policy: ref-counted (RefPtr), checked (CheckedPtr),...
virtual void describeHazard(llvm::raw_ostream &Os, const Expr *, QualType SinkType) const
Prints a phrase describing why the reported value is unsafe, completing a sentence of the form "Local...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isCocoaObjectRef(QualType T)
constexpr bool isPtrType(PrimType T)
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
std::unique_ptr< PtrRefSafetyModel > makeBorrowSafetyModel()
bool isExprToGetCheckedPtrCapableMember(const clang::Expr *E)
QualType pointeeType(QualType T)
std::optional< bool > isUnchecked(const QualType T)
QualType borrowedType(QualType T)
bool isRefOrCheckedPtrType(const clang::QualType T)
bool isView(const clang::QualType T)
std::unique_ptr< PtrRefSafetyModel > makeCheckedPtrSafetyModel()
void printQuotedQualifiedName(llvm::raw_ostream &Os, const NamedDeclDerivedT &D)
bool isRetainPtrOrOSPtrType(const clang::QualType T)
std::optional< bool > isUnsafePtrForStorage(const PtrRefSafetyModel &Model, QualType T, bool IgnoreARC=false)
Applies the memory-management exemptions that hold for a variable, member, or lambda capture (but not...
bool isBorrow(const clang::CXXRecordDecl *R)
std::optional< bool > isBorrowable(const clang::CXXRecordDecl *R)
const FunctionProtoType * T
bool isRefCounted(const CXXRecordDecl *R)
bool isRetainPtrOrOSPtr(const std::string &Name)
bool isRefType(const std::string &Name)
std::optional< bool > isUncountedPtr(const QualType T)
bool isSafePtr(clang::CXXRecordDecl *Decl)
bool isCheckedPtr(const std::string &Name)
bool isBorrowType(const clang::QualType T)
std::unique_ptr< PtrRefSafetyModel > makeRefPtrSafetyModel()
std::unique_ptr< PtrRefSafetyModel > makeRetainPtrSafetyModel()
std::optional< bool > isUncounted(const QualType T)
std::optional< bool > isUncheckedPtr(const QualType T)