[clang] 5f8b256 - Check the type of Objective-C++ instance variables in WebKit member variable checkers. (#127570)

via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 19 13:24:16 PST 2025


Author: Ryosuke Niwa
Date: 2025-02-19T13:24:12-08:00
New Revision: 5f8b2568219d5e516928aed67f13b59de8ccee17

URL: https://github.com/llvm/llvm-project/commit/5f8b2568219d5e516928aed67f13b59de8ccee17
DIFF: https://github.com/llvm/llvm-project/commit/5f8b2568219d5e516928aed67f13b59de8ccee17.diff

LOG: Check the type of Objective-C++ instance variables in WebKit member variable checkers. (#127570)

Like a C++ member variable, every Objective-C++ instance variable must
be a RefPtr, Ref CheckedPtr, or CheckedRef to an object, not a raw
pointer or reference.

Added: 
    clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm
    clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm

Modified: 
    clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index 79f88553feb95..963f59831c8ed 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -61,6 +61,11 @@ class RawPtrRefMemberChecker
         Checker->visitRecordDecl(RD);
         return true;
       }
+
+      bool VisitObjCContainerDecl(const ObjCContainerDecl *CD) override {
+        Checker->visitObjCDecl(CD);
+        return true;
+      }
     };
 
     LocalVisitor visitor(this);
@@ -87,6 +92,31 @@ class RawPtrRefMemberChecker
     }
   }
 
+  void visitObjCDecl(const ObjCContainerDecl *CD) const {
+    if (auto *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
+      for (auto *Ivar : ID->ivars())
+        visitIvarDecl(CD, Ivar);
+      return;
+    }
+    if (auto *ID = dyn_cast<ObjCImplementationDecl>(CD)) {
+      for (auto *Ivar : ID->ivars())
+        visitIvarDecl(CD, Ivar);
+      return;
+    }
+  }
+
+  void visitIvarDecl(const ObjCContainerDecl *CD,
+                     const ObjCIvarDecl *Ivar) const {
+    const Type *IvarType = Ivar->getType().getTypePtrOrNull();
+    if (!IvarType)
+      return;
+    if (auto *IvarCXXRD = IvarType->getPointeeCXXRecordDecl()) {
+      std::optional<bool> IsCompatible = isPtrCompatible(IvarCXXRD);
+      if (IsCompatible && *IsCompatible)
+        reportBug(Ivar, IvarType, IvarCXXRD, CD);
+    }
+  }
+
   bool shouldSkipDecl(const RecordDecl *RD) const {
     if (!RD->isThisDeclarationADefinition())
       return true;
@@ -121,9 +151,10 @@ class RawPtrRefMemberChecker
     return false;
   }
 
-  void reportBug(const FieldDecl *Member, const Type *MemberType,
+  template <typename DeclType, typename ParentDeclType>
+  void reportBug(const DeclType *Member, const Type *MemberType,
                  const CXXRecordDecl *MemberCXXRD,
-                 const RecordDecl *ClassCXXRD) const {
+                 const ParentDeclType *ClassCXXRD) const {
     assert(Member);
     assert(MemberType);
     assert(MemberCXXRD);
@@ -131,7 +162,10 @@ class RawPtrRefMemberChecker
     SmallString<100> Buf;
     llvm::raw_svector_ostream Os(Buf);
 
-    Os << "Member variable ";
+    if (isa<ObjCContainerDecl>(ClassCXXRD))
+      Os << "Instance variable ";
+    else
+      Os << "Member variable ";
     printQuotedName(Os, Member);
     Os << " in ";
     printQuotedQualifiedName(Os, ClassCXXRD);

diff  --git a/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm b/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm
new file mode 100644
index 0000000000000..a9a9a367fb9f4
--- /dev/null
+++ b/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm
@@ -0,0 +1,35 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.NoUncheckedPtrMemberChecker -verify %s
+
+#include "mock-types.h"
+
+__attribute__((objc_root_class))
+ at interface NSObject
++ (instancetype) alloc;
+- (instancetype) init;
+- (instancetype)retain;
+- (void)release;
+ at end
+
+void doSomeWork();
+
+ at interface SomeObjC : NSObject {
+  CheckedObj* _unchecked1;
+// expected-warning at -1{{Instance variable '_unchecked1' in 'SomeObjC' is a raw pointer to CheckedPtr capable type 'CheckedObj'}}  
+  CheckedPtr<CheckedObj> _counted1;
+  [[clang::suppress]] CheckedObj* _unchecked2;
+}
+- (void)doWork;
+ at end
+
+ at implementation SomeObjC {
+  CheckedObj* _unchecked3;
+// expected-warning at -1{{Instance variable '_unchecked3' in 'SomeObjC' is a raw pointer to CheckedPtr capable type 'CheckedObj'}}
+  CheckedPtr<CheckedObj> _counted2;
+  [[clang::suppress]] CheckedObj* _unchecked4;
+}
+
+- (void)doWork {
+  doSomeWork();
+}
+
+ at end

diff  --git a/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm b/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm
new file mode 100644
index 0000000000000..83b08a6841d26
--- /dev/null
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm
@@ -0,0 +1,35 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=webkit.NoUncountedMemberChecker -verify %s
+
+#include "mock-types.h"
+
+__attribute__((objc_root_class))
+ at interface NSObject
++ (instancetype) alloc;
+- (instancetype) init;
+- (instancetype)retain;
+- (void)release;
+ at end
+
+void doSomeWork();
+
+ at interface SomeObjC : NSObject {
+  RefCountable* _uncounted1;
+// expected-warning at -1{{Instance variable '_uncounted1' in 'SomeObjC' is a raw pointer to ref-countable type 'RefCountable'}}  
+  RefPtr<RefCountable> _counted1;
+  [[clang::suppress]] RefCountable* _uncounted2;
+}
+- (void)doWork;
+ at end
+
+ at implementation SomeObjC {
+  RefCountable* _uncounted3;
+// expected-warning at -1{{Instance variable '_uncounted3' in 'SomeObjC' is a raw pointer to ref-countable type 'RefCountable'}}
+  RefPtr<RefCountable> _counted2;
+  [[clang::suppress]] RefCountable* _uncounted4;
+}
+
+- (void)doWork {
+  doSomeWork();
+}
+
+ at end


        


More information about the cfe-commits mailing list