Skip to content

Commit 321a7c3

Browse files
authored
[alpha.webkit.NoUnretainedMemberChecker] Only check @Property when @implementation is seen (#159947)
A @interface declaration with a raw pointer @Property does not necessarily mean it synthesizes ivar of that type. To determine whether such a synthesis happens or not, we must wait for @implementation to appear. So this PR makes the checker only validate @Property then.
1 parent c3cbd27 commit 321a7c3

File tree

3 files changed

+77
-12
lines changed

3 files changed

+77
-12
lines changed

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,16 @@ class RawPtrRefMemberChecker
130130
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
131131
return;
132132

133-
ObjCContainerDecl::PropertyMap map;
134-
CD->collectPropertiesToImplement(map);
135-
for (auto it : map)
136-
visitObjCPropertyDecl(CD, it.second);
137-
138-
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
139-
for (auto *Ivar : ID->ivars())
140-
visitIvarDecl(CD, Ivar);
141-
return;
142-
}
143133
if (auto *ID = dyn_cast<ObjCImplementationDecl>(CD)) {
134+
ObjCContainerDecl::PropertyMap map;
135+
CD->collectPropertiesToImplement(map);
136+
for (auto it : map)
137+
visitObjCPropertyDecl(CD, it.second);
138+
139+
if (auto *Interface = ID->getClassInterface()) {
140+
for (auto *Ivar : Interface->ivars())
141+
visitIvarDecl(CD, Ivar);
142+
}
144143
for (auto *PropImpl : ID->property_impls())
145144
visitPropImpl(CD, PropImpl);
146145
for (auto *Ivar : ID->ivars())

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ @interface AnotherObject : NSObject {
8484
@property(nonatomic, unsafe_unretained) NSString *prop_string3;
8585
// expected-warning@-1{{Property 'prop_string3' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
8686
@property(nonatomic, readonly) NSString *prop_string4;
87+
@property(nonatomic, readonly) NSString *prop_safe;
88+
@end
89+
90+
@implementation AnotherObject
91+
- (NSString *)prop_safe {
92+
return nil;
93+
}
94+
@end
95+
96+
// No warnings for @interface declaration itself.
97+
@interface InterfaceOnlyObject : NSObject
98+
@property(nonatomic, strong) NSString *prop_string1;
99+
@property(nonatomic, assign) NSString *prop_string2;
100+
@property(nonatomic, unsafe_unretained) NSString *prop_string3;
101+
@property(nonatomic, readonly) NSString *prop_string4;
87102
@property(nonatomic, readonly) dispatch_queue_t prop_string5;
88103
@end
89104

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

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,59 @@ @interface AnotherObject : NSObject {
112112
dispatch_queue_t dispatch;
113113
// expected-warning@-1{{Instance variable 'dispatch' in 'AnotherObject' is a retainable type 'dispatch_queue_t'}}
114114
}
115-
@property(nonatomic, strong) NSString *prop_string;
116-
// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'}}
115+
@property(nonatomic, readonly, strong) NSString *prop_string;
116+
// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
117+
@property(nonatomic, readonly) NSString *prop_safe;
118+
@end
119+
120+
@implementation AnotherObject
121+
- (NSString *)prop_safe {
122+
return nil;
123+
}
124+
@end
125+
126+
@interface DerivedObject : AnotherObject {
127+
NSNumber *ns_number;
128+
// expected-warning@-1{{Instance variable 'ns_number' in 'DerivedObject' is a raw pointer to retainable type 'NSNumber'}}
129+
CGImageRef cg_image;
130+
// expected-warning@-1{{Instance variable 'cg_image' in 'DerivedObject' is a retainable type 'CGImageRef'}}
131+
dispatch_queue_t os_dispatch;
132+
// expected-warning@-1{{Instance variable 'os_dispatch' in 'DerivedObject' is a retainable type 'dispatch_queue_t'}}
133+
}
134+
@property(nonatomic, strong) NSNumber *prop_number;
135+
// expected-warning@-1{{Property 'prop_number' in 'DerivedObject' is a raw pointer to retainable type 'NSNumber'; member variables must be a RetainPtr}}
136+
@property(nonatomic, readonly) NSString *prop_string;
137+
@end
138+
139+
@implementation DerivedObject
140+
- (NSString *)prop_string {
141+
return nil;
142+
}
143+
@end
144+
145+
// No warnings for @interface declaration itself.
146+
@interface InterfaceOnlyObject : NSObject
147+
@property(nonatomic, strong) NSString *prop_string1;
148+
@property(nonatomic, assign) NSString *prop_string2;
149+
@property(nonatomic, unsafe_unretained) NSString *prop_string3;
150+
@property(nonatomic, readonly) NSString *prop_string4;
151+
@end
152+
153+
@interface InterfaceOnlyObject2 : NSObject
154+
@property(nonatomic, strong) NSString *prop_string1;
155+
@property(nonatomic, assign) NSString *prop_string2;
156+
@property(nonatomic, unsafe_unretained) NSString *prop_string3;
157+
// expected-warning@-1{{Property 'prop_string3' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}}
158+
@property(nonatomic, readonly) NSString *prop_string4;
159+
@end
160+
161+
@interface DerivedObject2 : InterfaceOnlyObject2
162+
@property(nonatomic, readonly) NSString *prop_string5;
163+
// expected-warning@-1{{Property 'prop_string5' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}}
164+
@end
165+
166+
@implementation DerivedObject2
167+
@synthesize prop_string3;
117168
@end
118169

119170
NS_REQUIRES_PROPERTY_DEFINITIONS

0 commit comments

Comments
 (0)