@@ -135,7 +135,16 @@ bool isCtorOfRefCounted(const clang::FunctionDecl *F) {
135135 || FunctionName == " Identifier" ;
136136}
137137
138- bool isRefType (const clang::QualType T) {
138+ bool isCtorOfCheckedPtr (const clang::FunctionDecl *F) {
139+ assert (F);
140+ return isCheckedPtr (safeGetName (F));
141+ }
142+
143+ bool isCtorOfSafePtr (const clang::FunctionDecl *F) {
144+ return isCtorOfRefCounted (F) || isCtorOfCheckedPtr (F);
145+ }
146+
147+ bool isSafePtrType (const clang::QualType T) {
139148 QualType type = T;
140149 while (!type.isNull ()) {
141150 if (auto *elaboratedT = type->getAs <ElaboratedType>()) {
@@ -145,7 +154,7 @@ bool isRefType(const clang::QualType T) {
145154 if (auto *specialT = type->getAs <TemplateSpecializationType>()) {
146155 if (auto *decl = specialT->getTemplateName ().getAsTemplateDecl ()) {
147156 auto name = decl->getNameAsString ();
148- return isRefType (name);
157+ return isRefType (name) || isCheckedPtr (name) ;
149158 }
150159 return false ;
151160 }
@@ -177,6 +186,12 @@ std::optional<bool> isUncounted(const CXXRecordDecl* Class)
177186 return (*IsRefCountable);
178187}
179188
189+ std::optional<bool > isUnchecked (const CXXRecordDecl *Class) {
190+ if (isCheckedPtr (Class))
191+ return false ; // Cheaper than below
192+ return isCheckedPtrCapable (Class);
193+ }
194+
180195std::optional<bool > isUncountedPtr (const QualType T) {
181196 if (T->isPointerType () || T->isReferenceType ()) {
182197 if (auto *CXXRD = T->getPointeeCXXRecordDecl ())
@@ -185,15 +200,26 @@ std::optional<bool> isUncountedPtr(const QualType T) {
185200 return false ;
186201}
187202
188- std::optional<bool > isGetterOfRefCounted (const CXXMethodDecl* M)
189- {
203+ std::optional<bool > isUnsafePtr (const QualType T) {
204+ if (T->isPointerType () || T->isReferenceType ()) {
205+ if (auto *CXXRD = T->getPointeeCXXRecordDecl ()) {
206+ return isUncounted (CXXRD) || isUnchecked (CXXRD);
207+ }
208+ }
209+ return false ;
210+ }
211+
212+ std::optional<bool > isGetterOfSafePtr (const CXXMethodDecl *M) {
190213 assert (M);
191214
192215 if (isa<CXXMethodDecl>(M)) {
193216 const CXXRecordDecl *calleeMethodsClass = M->getParent ();
194217 auto className = safeGetName (calleeMethodsClass);
195218 auto method = safeGetName (M);
196219
220+ if (isCheckedPtr (className) && (method == " get" || method == " ptr" ))
221+ return true ;
222+
197223 if ((isRefType (className) && (method == " get" || method == " ptr" )) ||
198224 ((className == " String" || className == " AtomString" ||
199225 className == " AtomStringImpl" || className == " UniqueString" ||
@@ -205,7 +231,12 @@ std::optional<bool> isGetterOfRefCounted(const CXXMethodDecl* M)
205231 // FIXME: Currently allowing any Ref<T> -> whatever cast.
206232 if (isRefType (className)) {
207233 if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M))
208- return isUncountedPtr (maybeRefToRawOperator->getConversionType ());
234+ return isUnsafePtr (maybeRefToRawOperator->getConversionType ());
235+ }
236+
237+ if (isCheckedPtr (className)) {
238+ if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M))
239+ return isUnsafePtr (maybeRefToRawOperator->getConversionType ());
209240 }
210241 }
211242 return false ;
@@ -448,7 +479,7 @@ class TrivialFunctionAnalysisVisitor
448479 if (!Callee)
449480 return false ;
450481
451- std::optional<bool > IsGetterOfRefCounted = isGetterOfRefCounted (Callee);
482+ std::optional<bool > IsGetterOfRefCounted = isGetterOfSafePtr (Callee);
452483 if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
453484 return true ;
454485
0 commit comments