1//=======- PtrTypesSemantics.cpp ---------------------------------*- 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#ifndef LLVM_CLANG_ANALYZER_WEBKIT_PTRTYPESEMANTICS_H
10#define LLVM_CLANG_ANALYZER_WEBKIT_PTRTYPESEMANTICS_H
11
12#include "llvm/ADT/APInt.h"
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/DenseSet.h"
15#include "llvm/ADT/PointerUnion.h"
16#include <optional>
17
18namespace clang {
19class CXXBaseSpecifier;
20class CXXMethodDecl;
21class CXXRecordDecl;
22class Decl;
23class FunctionDecl;
24class NamedDecl;
25class QualType;
26class RecordType;
27class Stmt;
28class TranslationUnitDecl;
29class Type;
30class TypedefDecl;
31class VarDecl;
32
33// Ref-countability of a type is implicitly defined by Ref<T> and RefPtr<T>
34// implementation. It can be modeled as: type T having public methods ref() and
35// deref()
36
37// In WebKit there are two ref-counted templated smart pointers: RefPtr<T> and
38// Ref<T>.
39
40/// \returns CXXRecordDecl of the base if the type has ref as a public method,
41/// nullptr if not, std::nullopt if inconclusive.
42std::optional<const clang::CXXRecordDecl *>
43hasPublicMethodInBase(const CXXBaseSpecifier *Base,
44 llvm::StringRef NameToMatch);
45
46/// \returns true if \p Class is ref-countable, false if not, std::nullopt if
47/// inconclusive.
48std::optional<bool> isRefCountable(const clang::CXXRecordDecl *Class);
49
50/// \returns true if \p Class is checked-pointer compatible, false if not,
51/// std::nullopt if inconclusive.
52std::optional<bool> isCheckedPtrCapable(const clang::CXXRecordDecl *Class);
53
54/// \returns true if \p Class is ref-counted, false if not.
55bool isRefCounted(const clang::CXXRecordDecl *Class);
56
57/// \returns true if \p Class is a CheckedPtr / CheckedRef, false if not.
58bool isCheckedPtr(const clang::CXXRecordDecl *Class);
59
60/// \returns true if \p Class is a RetainPtr, false if not.
61bool isRetainPtrOrOSPtr(const clang::CXXRecordDecl *Class);
62
63/// \returns true if \p Class is a smart pointer (RefPtr, WeakPtr, etc...),
64/// false if not.
65bool isSmartPtr(const clang::CXXRecordDecl *Class);
66
67/// \returns true if \p Class is ref-countable AND not ref-counted, false if
68/// not, std::nullopt if inconclusive.
69std::optional<bool> isUncounted(const clang::QualType T);
70
71/// \returns true if \p Class is CheckedPtr capable AND not checked, false if
72/// not, std::nullopt if inconclusive.
73std::optional<bool> isUnchecked(const clang::QualType T);
74
75/// An inter-procedural analysis facility that detects CF types with the
76/// underlying pointer type.
77class RetainTypeChecker {
78 llvm::DenseSet<const RecordType *> CFPointees;
79 llvm::DenseSet<const Type *> RecordlessTypes;
80 bool IsARCEnabled{false};
81 bool DefaultSynthProperties{true};
82
83public:
84 void visitTranslationUnitDecl(const TranslationUnitDecl *);
85 void visitTypedef(const TypedefDecl *);
86 bool isUnretained(const QualType, bool ignoreARC = false);
87 bool isARCEnabled() const { return IsARCEnabled; }
88 bool defaultSynthProperties() const { return DefaultSynthProperties; }
89};
90
91/// \returns true if \p Class is ref-countable AND not ref-counted, false if
92/// not, std::nullopt if inconclusive.
93std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class);
94
95/// \returns true if \p Class is CheckedPtr capable AND not checked, false if
96/// not, std::nullopt if inconclusive.
97std::optional<bool> isUnchecked(const clang::CXXRecordDecl *Class);
98
99/// \returns true if \p T is either a raw pointer or reference to an uncounted
100/// class, false if not, std::nullopt if inconclusive.
101std::optional<bool> isUncountedPtr(const clang::QualType T);
102
103/// \returns true if \p T is either a raw pointer or reference to an unchecked
104/// class, false if not, std::nullopt if inconclusive.
105std::optional<bool> isUncheckedPtr(const clang::QualType T);
106
107/// \returns true if \p T is a RefPtr, Ref, CheckedPtr, CheckedRef, or its
108/// variant, false if not.
109bool isRefOrCheckedPtrType(const clang::QualType T);
110
111/// \returns true if \p T is a RetainPtr, false if not.
112bool isRetainPtrOrOSPtrType(const clang::QualType T);
113
114/// \returns true if \p T is a RefPtr, Ref, CheckedPtr, CheckedRef, or
115/// unique_ptr, false if not.
116bool isOwnerPtrType(const clang::QualType T);
117
118/// \returns true if \p F creates ref-countable object from uncounted parameter,
119/// false if not.
120bool isCtorOfRefCounted(const clang::FunctionDecl *F);
121
122/// \returns true if \p F creates checked ptr object from uncounted parameter,
123/// false if not.
124bool isCtorOfCheckedPtr(const clang::FunctionDecl *F);
125
126/// \returns true if \p F creates ref-countable or checked ptr object from
127/// uncounted parameter, false if not.
128bool isCtorOfSafePtr(const clang::FunctionDecl *F);
129
130/// \returns true if \p F is std::move or WTF::move.
131bool isStdOrWTFMove(const clang::FunctionDecl *F);
132
133/// \returns true if \p Name is RefPtr, Ref, or its variant, false if not.
134bool isRefType(const std::string &Name);
135
136/// \returns true if \p Name is CheckedRef or CheckedPtr, false if not.
137bool isCheckedPtr(const std::string &Name);
138
139/// \returns true if \p Name is RetainPtr or its variant, false if not.
140bool isRetainPtrOrOSPtr(const std::string &Name);
141
142/// \returns true if \p Name is an owning smar pointer such as Ref, CheckedPtr,
143/// and unique_ptr.
144bool isOwnerPtr(const std::string &Name);
145
146/// \returns true if \p Name is a smart pointer type name, false if not.
147bool isSmartPtrClass(const std::string &Name);
148
149/// \returns true if \p M is getter of a ref-counted class, false if not.
150std::optional<bool> isGetterOfSafePtr(const clang::CXXMethodDecl *Method);
151
152/// \returns true if \p F is a conversion between ref-countable or ref-counted
153/// pointer types.
154bool isPtrConversion(const FunctionDecl *F);
155
156/// \returns true if \p F's return type is annotated with
157/// [[clang::annotate_type("webkit.nodelete")]].
158bool isNoDeleteFunction(const FunctionDecl *F);
159
160/// \returns true if \p F is a builtin function which is considered trivial.
161bool isTrivialBuiltinFunction(const FunctionDecl *F);
162
163/// \returns true if \p F is a static singleton function.
164bool isSingleton(const NamedDecl *F);
165
166/// An inter-procedural analysis facility that detects functions with "trivial"
167/// behavior with respect to reference counting, such as simple field getters.
168class TrivialFunctionAnalysis {
169public:
170 /// \returns true if \p D is a "trivial" function.
171 bool isTrivial(const Decl *D, const Stmt **OffendingStmt = nullptr) const {
172 return isTrivialImpl(D, Cache&: TheCache, OffendingStmt);
173 }
174 bool isTrivial(const Stmt *S, const Stmt **OffendingStmt = nullptr) const {
175 return isTrivialImpl(S, Cache&: TheCache, OffendingStmt);
176 }
177 bool hasTrivialDtor(const VarDecl *VD) const {
178 return hasTrivialDtorImpl(VD, Cache&: TheCache);
179 }
180
181private:
182 friend class TrivialFunctionAnalysisVisitor;
183
184 using CacheTy =
185 llvm::DenseMap<llvm::PointerUnion<const Decl *, const Stmt *>, bool>;
186 mutable CacheTy TheCache{};
187
188 static bool isTrivialImpl(const Decl *D, CacheTy &Cache, const Stmt **);
189 static bool isTrivialImpl(const Stmt *S, CacheTy &Cache, const Stmt **);
190 static bool hasTrivialDtorImpl(const VarDecl *VD, CacheTy &Cache);
191};
192
193} // namespace clang
194
195#endif
196