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