Skip to content

Commit 450e359

Browse files
committed
[alpha.webkit.NoUnretainedMemberChecker] Only check @Property when @implementation is seen (llvm#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 cac15c9 commit 450e359

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
@@ -133,17 +133,16 @@ class RawPtrRefMemberChecker
133133
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
134134
return;
135135

136-
ObjCContainerDecl::PropertyMap map;
137-
CD->collectPropertiesToImplement(map);
138-
for (auto it : map)
139-
visitObjCPropertyDecl(CD, it.second);
140-
141-
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
142-
for (auto *Ivar : ID->ivars())
143-
visitIvarDecl(CD, Ivar);
144-
return;
145-
}
146136
if (auto *ID = dyn_cast<ObjCImplementationDecl>(CD)) {
137+
ObjCContainerDecl::PropertyMap map;
138+
CD->collectPropertiesToImplement(map);
139+
for (auto it : map)
140+
visitObjCPropertyDecl(CD, it.second);
141+
142+
if (auto *Interface = ID->getClassInterface()) {
143+
for (auto *Ivar : Interface->ivars())
144+
visitIvarDecl(CD, Ivar);
145+
}
147146
for (auto *PropImpl : ID->property_impls())
148147
visitPropImpl(CD, PropImpl);
149148
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)