Author: Ryosuke Niwa
Date: 2025-04-15T20:00:51-07:00
New Revision: 517605c20e6014543e91d45524a17c443aa11bd4

URL: 
https://github.com/llvm/llvm-project/commit/517605c20e6014543e91d45524a17c443aa11bd4
DIFF: 
https://github.com/llvm/llvm-project/commit/517605c20e6014543e91d45524a17c443aa11bd4.diff

LOG: [alpha.webkit.UnretainedCallArgsChecker] Add the support for RetainPtrArc 
(#135532)

WebKit uses #define to rename RetainPtr to RetainPtrArc so add the
support for it.

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
    clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
    clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
    clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
    clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 134afcd124526..811888e119449 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -119,7 +119,9 @@ bool isRefType(const std::string &Name) {
          Name == "RefPtr" || Name == "RefPtrAllowingPartiallyDestroyed";
 }
 
-bool isRetainPtr(const std::string &Name) { return Name == "RetainPtr"; }
+bool isRetainPtr(const std::string &Name) {
+  return Name == "RetainPtr" || Name == "RetainPtrArc";
+}
 
 bool isCheckedPtr(const std::string &Name) {
   return Name == "CheckedPtr" || Name == "CheckedRef";
@@ -157,7 +159,8 @@ bool isCtorOfCheckedPtr(const clang::FunctionDecl *F) {
 bool isCtorOfRetainPtr(const clang::FunctionDecl *F) {
   const std::string &FunctionName = safeGetName(F);
   return FunctionName == "RetainPtr" || FunctionName == "adoptNS" ||
-         FunctionName == "adoptCF" || FunctionName == "retainPtr";
+         FunctionName == "adoptCF" || FunctionName == "retainPtr" ||
+         FunctionName == "RetainPtrArc" || FunctionName == "adoptNSArc";
 }
 
 bool isCtorOfSafePtr(const clang::FunctionDecl *F) {
@@ -190,7 +193,7 @@ bool isRefOrCheckedPtrType(const clang::QualType T) {
 }
 
 bool isRetainPtrType(const clang::QualType T) {
-  return isPtrOfType(T, [](auto Name) { return Name == "RetainPtr"; });
+  return isPtrOfType(T, [](auto Name) { return isRetainPtr(Name); });
 }
 
 bool isOwnerPtrType(const clang::QualType T) {
@@ -374,7 +377,7 @@ std::optional<bool> isGetterOfSafePtr(const CXXMethodDecl 
*M) {
          method == "impl"))
       return true;
 
-    if (className == "RetainPtr" && method == "get")
+    if (isRetainPtr(className) && method == "get")
       return true;
 
     // Ref<T> -> T conversion
@@ -395,7 +398,7 @@ std::optional<bool> isGetterOfSafePtr(const CXXMethodDecl 
*M) {
       }
     }
 
-    if (className == "RetainPtr") {
+    if (isRetainPtr(className)) {
       if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
         auto QT = maybeRefToRawOperator->getConversionType();
         auto *T = QT.getTypePtrOrNull();
@@ -429,7 +432,7 @@ bool isCheckedPtr(const CXXRecordDecl *R) {
 bool isRetainPtr(const CXXRecordDecl *R) {
   assert(R);
   if (auto *TmplR = R->getTemplateInstantiationPattern())
-    return safeGetName(TmplR) == "RetainPtr";
+    return isRetainPtr(safeGetName(TmplR));
   return false;
 }
 

diff  --git 
a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
index d372c5d1ba626..d3eee11311d91 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
@@ -71,7 +71,7 @@ class RetainPtrCtorAdoptChecker
       }
 
       bool TraverseClassTemplateDecl(ClassTemplateDecl *CTD) {
-        if (safeGetName(CTD) == "RetainPtr")
+        if (isRetainPtr(safeGetName(CTD)))
           return true; // Skip the contents of RetainPtr.
         return Base::TraverseClassTemplateDecl(CTD);
       }
@@ -193,7 +193,7 @@ class RetainPtrCtorAdoptChecker
     if (!Cls)
       return;
 
-    if (safeGetName(Cls) != "RetainPtr" || !CE->getNumArgs())
+    if (!isRetainPtr(safeGetName(Cls)) || !CE->getNumArgs())
       return;
 
     // Ignore RetainPtr construction inside adoptNS, adoptCF, and retainPtr.
@@ -322,12 +322,12 @@ class RetainPtrCtorAdoptChecker
           if (auto *CD = dyn_cast<CXXConversionDecl>(MD)) {
             auto QT = CD->getConversionType().getCanonicalType();
             auto *ResultType = QT.getTypePtrOrNull();
-            if (safeGetName(Cls) == "RetainPtr" && ResultType &&
+            if (isRetainPtr(safeGetName(Cls)) && ResultType &&
                 (ResultType->isPointerType() || ResultType->isReferenceType() 
||
                  ResultType->isObjCObjectPointerType()))
               return IsOwnedResult::NotOwned;
           }
-          if (safeGetName(MD) == "leakRef" && safeGetName(Cls) == "RetainPtr")
+          if (safeGetName(MD) == "leakRef" && isRetainPtr(safeGetName(Cls)))
             return IsOwnedResult::Owned;
         }
       }

diff  --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h 
b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
index 51de81ac0f033..a4332df682060 100644
--- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
@@ -17,6 +17,7 @@ typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * 
CFStringRef;
 typedef const struct CF_BRIDGED_TYPE(NSArray) __CFArray * CFArrayRef;
 typedef struct CF_BRIDGED_MUTABLE_TYPE(NSMutableArray) __CFArray * 
CFMutableArrayRef;
 typedef struct CF_BRIDGED_MUTABLE_TYPE(CFRunLoopRef) __CFRunLoop * 
CFRunLoopRef;
+typedef struct CF_BRIDGED_TYPE(id) CGImage *CGImageRef;
 
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
 #define CF_CONSUMED __attribute__((cf_consumed))
@@ -150,6 +151,10 @@ namespace WTF {
 
 void WTFCrash(void);
 
+#if __has_feature(objc_arc)
+#define RetainPtr RetainPtrArc
+#endif
+
 template<typename T> class RetainPtr;
 template<typename T> RetainPtr<T> adoptNS(T*);
 template<typename T> RetainPtr<T> adoptCF(T);

diff  --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm 
b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
index f1f4d912663aa..4207c1836079f 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
@@ -5,6 +5,8 @@
 SomeObj *provide();
 CFMutableArrayRef provide_cf();
 void someFunction();
+CGImageRef provideImage();
+NSString *stringForImage(CGImageRef);
 
 namespace raw_ptr {
 
@@ -36,4 +38,13 @@ - (SomeObj *)getSomeObj {
 - (void)doWorkOnSomeObj {
     [[self getSomeObj] doWork];
 }
+
+- (CGImageRef)createImage {
+  return provideImage();
+}
+
+- (NSString *)convertImage {
+  RetainPtr<CGImageRef> image = [self createImage];
+  return stringForImage(image.get());
+}
 @end

diff  --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm 
b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index 0667e4964f1a8..eb36b49313d42 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -9,6 +9,9 @@
 CFMutableArrayRef provide_cf();
 void consume_cf(CFMutableArrayRef);
 
+CGImageRef provideImage();
+NSString *stringForImage(CGImageRef);
+
 void some_function();
 
 namespace simple {
@@ -440,4 +443,12 @@ - (void)doWorkOnSomeObj {
     [[self getSomeObj] doWork];
 }
 
+- (CGImageRef)createImage {
+  return provideImage();
+}
+
+- (NSString *)convertImage {
+  RetainPtr<CGImageRef> image = [self createImage];
+  return stringForImage(image.get());
+}
 @end


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to