[clang] 304b3c5 - [alpha.webkit.RawPtrRefMemberChecker] The checker doesn't warn Objective-C types in ivars. (#132833)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 28 17:34:54 PDT 2025
Author: Ryosuke Niwa
Date: 2025-03-28T17:34:51-07:00
New Revision: 304b3c500021a9281a1d03cf3a63380ca31f7451
URL: https://github.com/llvm/llvm-project/commit/304b3c500021a9281a1d03cf3a63380ca31f7451
DIFF: https://github.com/llvm/llvm-project/commit/304b3c500021a9281a1d03cf3a63380ca31f7451.diff
LOG: [alpha.webkit.RawPtrRefMemberChecker] The checker doesn't warn Objective-C types in ivars. (#132833)
This PR fixes the bug that we weren't generating warnings when a raw
poiner is used to point to a NS type in Objective-C ivars. Also fix the
bug that we weren't suppressing this warning in system headers.
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
clang/test/Analysis/Checkers/WebKit/mock-system-header.h
clang/test/Analysis/Checkers/WebKit/unretained-members.mm
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index dc4e2c7d168fb..89df1a725ab92 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -111,6 +111,14 @@ class RawPtrRefMemberChecker
}
void visitObjCDecl(const ObjCContainerDecl *CD) const {
+ if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
+ return;
+
+ ObjCContainerDecl::PropertyMap map;
+ CD->collectPropertiesToImplement(map);
+ for (auto it : map)
+ visitObjCPropertyDecl(CD, it.second);
+
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
for (auto *Ivar : ID->ivars())
visitIvarDecl(CD, Ivar);
@@ -133,6 +141,35 @@ class RawPtrRefMemberChecker
std::optional<bool> IsCompatible = isPtrCompatible(QT, IvarCXXRD);
if (IsCompatible && *IsCompatible)
reportBug(Ivar, IvarType, IvarCXXRD, CD);
+ } else {
+ std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
+ auto *PointeeType = IvarType->getPointeeType().getTypePtrOrNull();
+ if (IsCompatible && *IsCompatible) {
+ auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
+ if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
+ reportBug(Ivar, IvarType, ObjCType->getDecl(), CD);
+ }
+ }
+ }
+
+ void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
+ const ObjCPropertyDecl *PD) const {
+ auto QT = PD->getType();
+ const Type *PropType = QT.getTypePtrOrNull();
+ if (!PropType)
+ return;
+ if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl()) {
+ std::optional<bool> IsCompatible = isPtrCompatible(QT, PropCXXRD);
+ if (IsCompatible && *IsCompatible)
+ reportBug(PD, PropType, PropCXXRD, CD);
+ } else {
+ std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
+ auto *PointeeType = PropType->getPointeeType().getTypePtrOrNull();
+ if (IsCompatible && *IsCompatible) {
+ auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
+ if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
+ reportBug(PD, PropType, ObjCType->getDecl(), CD);
+ }
}
}
@@ -181,9 +218,12 @@ class RawPtrRefMemberChecker
SmallString<100> Buf;
llvm::raw_svector_ostream Os(Buf);
- if (isa<ObjCContainerDecl>(ClassCXXRD))
- Os << "Instance variable ";
- else
+ if (isa<ObjCContainerDecl>(ClassCXXRD)) {
+ if (isa<ObjCPropertyDecl>(Member))
+ Os << "Property ";
+ else
+ Os << "Instance variable ";
+ } else
Os << "Member variable ";
printQuotedName(Os, Member);
Os << " in ";
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-system-header.h b/clang/test/Analysis/Checkers/WebKit/mock-system-header.h
index e993fd697ffab..450fb24687343 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-system-header.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-system-header.h
@@ -29,3 +29,14 @@ enum os_log_type_t : uint8_t {
typedef struct os_log_s *os_log_t;
os_log_t os_log_create(const char *subsystem, const char *category);
void os_log_msg(os_log_t oslog, os_log_type_t type, const char *msg, ...);
+
+typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef;
+
+#ifdef __OBJC__
+ at class NSString;
+ at interface SystemObject {
+ NSString *ns_string;
+ CFStringRef cf_string;
+}
+ at end
+#endif
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
index e068a583c18c5..92d70a94427c0 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
@@ -1,6 +1,7 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.NoUnretainedMemberChecker -verify %s
#include "objc-mock-types.h"
+#include "mock-system-header.h"
namespace members {
@@ -58,3 +59,13 @@ void forceTmplToInstantiate(FooTmpl<SomeObj, CFMutableArrayRef>) {}
void forceTmplToInstantiate(RefPtr<SomeObj>) {}
}
+
+ at interface AnotherObject : NSObject {
+ NSString *ns_string;
+ // expected-warning at -1{{Instance variable 'ns_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
+ CFStringRef cf_string;
+ // expected-warning at -1{{Instance variable 'cf_string' in 'AnotherObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
+}
+ at property(nonatomic, strong) NSString *prop_string;
+// expected-warning at -1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
+ at end
More information about the cfe-commits
mailing list