Skip to content

Commit bd7daa3

Browse files
committed
[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.
1 parent 436504c commit bd7daa3

File tree

6 files changed

+45
-0
lines changed

6 files changed

+45
-0
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ std::optional<bool> isUnchecked(const QualType T) {
236236
void RetainTypeChecker::visitTranslationUnitDecl(
237237
const TranslationUnitDecl *TUD) {
238238
IsARCEnabled = TUD->getLangOpts().ObjCAutoRefCount;
239+
DefaultSynthProperties = TUD->getLangOpts().ObjCDefaultSynthProperties;
239240
}
240241

241242
void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ class RetainTypeChecker {
7676
llvm::DenseSet<const RecordType *> CFPointees;
7777
llvm::DenseSet<const Type *> RecordlessTypes;
7878
bool IsARCEnabled{false};
79+
bool DefaultSynthProperties{true};
7980

8081
public:
8182
void visitTranslationUnitDecl(const TranslationUnitDecl *);
8283
void visitTypedef(const TypedefDecl *);
8384
bool isUnretained(const QualType, bool ignoreARC = false);
8485
bool isARCEnabled() const { return IsARCEnabled; }
86+
bool defaultSynthProperties() const { return DefaultSynthProperties; }
8587
};
8688

8789
/// \returns true if \p Class is NS or CF objects AND not retained, false if

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ class RawPtrRefMemberChecker
174174
if (!PropType)
175175
return;
176176

177+
if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
178+
if (!RTC || !RTC->defaultSynthProperties() || ID->isObjCRequiresPropertyDefs())
179+
return;
180+
}
181+
177182
auto IsUnsafePtr = isUnsafePtr(QT);
178183
if (!IsUnsafePtr || !*IsUnsafePtr)
179184
return;

clang/test/Analysis/Checkers/WebKit/objc-mock-types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typedef struct CF_BRIDGED_TYPE(id) CGImage *CGImageRef;
2222
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
2323
#define CF_CONSUMED __attribute__((cf_consumed))
2424
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
25+
#define NS_REQUIRES_PROPERTY_DEFINITIONS __attribute__((objc_requires_property_definitions))
2526

2627
extern const CFAllocatorRef kCFAllocatorDefault;
2728
typedef struct _NSZone NSZone;

clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,20 @@ void forceTmplToInstantiate(FooTmpl<SomeObj, CFMutableArrayRef>) {}
6464
};
6565

6666
} // namespace ptr_to_ptr_to_retained
67+
68+
NS_REQUIRES_PROPERTY_DEFINITIONS
69+
@interface NoSynthObject : NSObject {
70+
NSString *ns_string;
71+
CFStringRef cf_string;
72+
// expected-warning@-1{{Instance variable 'cf_string' in 'NoSynthObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
73+
}
74+
@property(nonatomic, readonly, strong) NSString *prop_string1;
75+
@property(nonatomic, readonly, strong) NSString *prop_string2;
76+
@end
77+
78+
@implementation NoSynthObject
79+
- (NSString *)prop_string1 {
80+
return nil;
81+
}
82+
@synthesize prop_string2;
83+
@end

clang/test/Analysis/Checkers/WebKit/unretained-members.mm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,22 @@ @interface AnotherObject : NSObject {
9999
@property(nonatomic, strong) NSString *prop_string;
100100
// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
101101
@end
102+
103+
NS_REQUIRES_PROPERTY_DEFINITIONS
104+
@interface NoSynthObject : NSObject {
105+
NSString *ns_string;
106+
// expected-warning@-1{{Instance variable 'ns_string' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
107+
CFStringRef cf_string;
108+
// expected-warning@-1{{Instance variable 'cf_string' in 'NoSynthObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
109+
}
110+
@property(nonatomic, readonly, strong) NSString *prop_string1;
111+
@property(nonatomic, readonly, strong) NSString *prop_string2;
112+
@end
113+
114+
@implementation NoSynthObject
115+
- (NSString *)prop_string1 {
116+
return nil;
117+
}
118+
@synthesize prop_string2;
119+
// expected-warning@-1{{Instance variable 'prop_string2' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'}}
120+
@end

0 commit comments

Comments
 (0)