Author: Ryosuke Niwa Date: 2025-09-25T11:12:23-07:00 New Revision: 321a7c3caf7c5c6a208501e1406fcab14f8b54f9
URL: https://github.com/llvm/llvm-project/commit/321a7c3caf7c5c6a208501e1406fcab14f8b54f9 DIFF: https://github.com/llvm/llvm-project/commit/321a7c3caf7c5c6a208501e1406fcab14f8b54f9.diff LOG: [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. Added: Modified: clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm 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 a97a37f85e96c..15a0c5a7fd9dc 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp @@ -130,17 +130,16 @@ class RawPtrRefMemberChecker 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); - return; - } if (auto *ID = dyn_cast<ObjCImplementationDecl>(CD)) { + ObjCContainerDecl::PropertyMap map; + CD->collectPropertiesToImplement(map); + for (auto it : map) + visitObjCPropertyDecl(CD, it.second); + + if (auto *Interface = ID->getClassInterface()) { + for (auto *Ivar : Interface->ivars()) + visitIvarDecl(CD, Ivar); + } for (auto *PropImpl : ID->property_impls()) visitPropImpl(CD, PropImpl); for (auto *Ivar : ID->ivars()) diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm index 19c54c4dc07ba..4eef372d26480 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm @@ -84,6 +84,21 @@ @interface AnotherObject : NSObject { @property(nonatomic, unsafe_unretained) NSString *prop_string3; // expected-warning@-1{{Property 'prop_string3' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}} @property(nonatomic, readonly) NSString *prop_string4; +@property(nonatomic, readonly) NSString *prop_safe; +@end + +@implementation AnotherObject +- (NSString *)prop_safe { + return nil; +} +@end + +// No warnings for @interface declaration itself. +@interface InterfaceOnlyObject : NSObject +@property(nonatomic, strong) NSString *prop_string1; +@property(nonatomic, assign) NSString *prop_string2; +@property(nonatomic, unsafe_unretained) NSString *prop_string3; +@property(nonatomic, readonly) NSString *prop_string4; @property(nonatomic, readonly) dispatch_queue_t prop_string5; @end diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm index 155848f9834af..adf1d8aef9d7d 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-members.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-members.mm @@ -112,8 +112,59 @@ @interface AnotherObject : NSObject { dispatch_queue_t dispatch; // expected-warning@-1{{Instance variable 'dispatch' in 'AnotherObject' is a retainable type 'dispatch_queue_t'}} } -@property(nonatomic, strong) NSString *prop_string; -// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'}} +@property(nonatomic, readonly, strong) NSString *prop_string; +// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}} +@property(nonatomic, readonly) NSString *prop_safe; +@end + +@implementation AnotherObject +- (NSString *)prop_safe { + return nil; +} +@end + +@interface DerivedObject : AnotherObject { + NSNumber *ns_number; + // expected-warning@-1{{Instance variable 'ns_number' in 'DerivedObject' is a raw pointer to retainable type 'NSNumber'}} + CGImageRef cg_image; + // expected-warning@-1{{Instance variable 'cg_image' in 'DerivedObject' is a retainable type 'CGImageRef'}} + dispatch_queue_t os_dispatch; + // expected-warning@-1{{Instance variable 'os_dispatch' in 'DerivedObject' is a retainable type 'dispatch_queue_t'}} +} +@property(nonatomic, strong) NSNumber *prop_number; +// expected-warning@-1{{Property 'prop_number' in 'DerivedObject' is a raw pointer to retainable type 'NSNumber'; member variables must be a RetainPtr}} +@property(nonatomic, readonly) NSString *prop_string; +@end + +@implementation DerivedObject +- (NSString *)prop_string { + return nil; +} +@end + +// No warnings for @interface declaration itself. +@interface InterfaceOnlyObject : NSObject +@property(nonatomic, strong) NSString *prop_string1; +@property(nonatomic, assign) NSString *prop_string2; +@property(nonatomic, unsafe_unretained) NSString *prop_string3; +@property(nonatomic, readonly) NSString *prop_string4; +@end + +@interface InterfaceOnlyObject2 : NSObject +@property(nonatomic, strong) NSString *prop_string1; +@property(nonatomic, assign) NSString *prop_string2; +@property(nonatomic, unsafe_unretained) NSString *prop_string3; +// expected-warning@-1{{Property 'prop_string3' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}} +@property(nonatomic, readonly) NSString *prop_string4; +@end + +@interface DerivedObject2 : InterfaceOnlyObject2 +@property(nonatomic, readonly) NSString *prop_string5; +// expected-warning@-1{{Property 'prop_string5' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}} +@end + +@implementation DerivedObject2 +@synthesize prop_string3; @end NS_REQUIRES_PROPERTY_DEFINITIONS _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
