[clang] [alpha.webkit.NoUnretainedMemberChecker] Recocgnize NS_REQUIRES_PROPERTY_DEFINITIONS (PR #141293)
Ryosuke Niwa via cfe-commits
cfe-commits at lists.llvm.org
Fri May 23 13:57:30 PDT 2025
https://github.com/rniwa created https://github.com/llvm/llvm-project/pull/141293
Allow @property of a raw pointer when NS_REQUIRES_PROPERTY_DEFINITIONS is specified on the interface since such an interface does not automatically synthesize raw pointer ivars.
>From bd7daa355f5c1924475c0818dd4963af7bbffcb1 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Fri, 23 May 2025 13:53:36 -0700
Subject: [PATCH] [alpha.webkit.NoUnretainedMemberChecker] Recocgnize
NS_REQUIRES_PROPERTY_DEFINITIONS
Allow @property of a raw pointer when NS_REQUIRES_PROPERTY_DEFINITIONS is specified on the interface
since such an interface does not automatically synthesize raw pointer ivars.
---
.../Checkers/WebKit/PtrTypesSemantics.cpp | 1 +
.../Checkers/WebKit/PtrTypesSemantics.h | 2 ++
.../WebKit/RawPtrRefMemberChecker.cpp | 5 +++++
.../Checkers/WebKit/objc-mock-types.h | 1 +
.../Checkers/WebKit/unretained-members-arc.mm | 17 +++++++++++++++++
.../Checkers/WebKit/unretained-members.mm | 19 +++++++++++++++++++
6 files changed, 45 insertions(+)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 4ddd11495f534..f547f86f4782f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -236,6 +236,7 @@ std::optional<bool> isUnchecked(const QualType T) {
void RetainTypeChecker::visitTranslationUnitDecl(
const TranslationUnitDecl *TUD) {
IsARCEnabled = TUD->getLangOpts().ObjCAutoRefCount;
+ DefaultSynthProperties = TUD->getLangOpts().ObjCDefaultSynthProperties;
}
void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
index f9fcfe9878d54..3c9560cb8059b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
@@ -76,12 +76,14 @@ class RetainTypeChecker {
llvm::DenseSet<const RecordType *> CFPointees;
llvm::DenseSet<const Type *> RecordlessTypes;
bool IsARCEnabled{false};
+ bool DefaultSynthProperties{true};
public:
void visitTranslationUnitDecl(const TranslationUnitDecl *);
void visitTypedef(const TypedefDecl *);
bool isUnretained(const QualType, bool ignoreARC = false);
bool isARCEnabled() const { return IsARCEnabled; }
+ bool defaultSynthProperties() const { return DefaultSynthProperties; }
};
/// \returns true if \p Class is NS or CF objects AND not retained, false if
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index 4ea6158c4c410..acd23b6eae7ea 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -174,6 +174,11 @@ class RawPtrRefMemberChecker
if (!PropType)
return;
+ if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
+ if (!RTC || !RTC->defaultSynthProperties() || ID->isObjCRequiresPropertyDefs())
+ return;
+ }
+
auto IsUnsafePtr = isUnsafePtr(QT);
if (!IsUnsafePtr || !*IsUnsafePtr)
return;
diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
index 93e7dfd77b9e9..9e4356a71f1b5 100644
--- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
@@ -22,6 +22,7 @@ typedef struct CF_BRIDGED_TYPE(id) CGImage *CGImageRef;
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
#define CF_CONSUMED __attribute__((cf_consumed))
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#define NS_REQUIRES_PROPERTY_DEFINITIONS __attribute__((objc_requires_property_definitions))
extern const CFAllocatorRef kCFAllocatorDefault;
typedef struct _NSZone NSZone;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm
index 3491bc93ed98a..ca2679900bebe 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm
@@ -64,3 +64,20 @@ void forceTmplToInstantiate(FooTmpl<SomeObj, CFMutableArrayRef>) {}
};
} // namespace ptr_to_ptr_to_retained
+
+NS_REQUIRES_PROPERTY_DEFINITIONS
+ at interface NoSynthObject : NSObject {
+ NSString *ns_string;
+ CFStringRef cf_string;
+ // expected-warning at -1{{Instance variable 'cf_string' in 'NoSynthObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
+}
+ at property(nonatomic, readonly, strong) NSString *prop_string1;
+ at property(nonatomic, readonly, strong) NSString *prop_string2;
+ at end
+
+ at implementation NoSynthObject
+- (NSString *)prop_string1 {
+ return nil;
+}
+ at synthesize prop_string2;
+ at end
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
index 0cb4c4ac0f6a0..7b31296378034 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm
@@ -99,3 +99,22 @@ @interface AnotherObject : NSObject {
@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}}
@end
+
+NS_REQUIRES_PROPERTY_DEFINITIONS
+ at interface NoSynthObject : NSObject {
+ NSString *ns_string;
+ // expected-warning at -1{{Instance variable 'ns_string' in 'NoSynthObject' 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 'NoSynthObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
+}
+ at property(nonatomic, readonly, strong) NSString *prop_string1;
+ at property(nonatomic, readonly, strong) NSString *prop_string2;
+ at end
+
+ at implementation NoSynthObject
+- (NSString *)prop_string1 {
+ return nil;
+}
+ at synthesize prop_string2;
+// expected-warning at -1{{Instance variable 'prop_string2' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'}}
+ at end
More information about the cfe-commits
mailing list