Skip to content

Commit c8d49e9

Browse files
authored
[alpha.webkit.RetainPtrCtorAdoptChecker] Recognize mutableCopy from literal as +1 (#132350)
This PR adds the support for recognizing the return value of copy / mutableCopy as +1. isAllocInit and isOwned now traverses PseudoObjectExpr to its last semantic expression.
1 parent f76d9da commit c8d49e9

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ class RetainPtrCtorAdoptChecker
202202

203203
bool isAllocInit(const Expr *E) const {
204204
auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E);
205+
if (auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
206+
if (unsigned ExprCount = POE->getNumSemanticExprs()) {
207+
auto *Expr = POE->getSemanticExpr(ExprCount - 1)->IgnoreParenCasts();
208+
ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(Expr);
209+
}
210+
}
205211
if (!ObjCMsgExpr)
206212
return false;
207213
auto Selector = ObjCMsgExpr->getSelector();
@@ -247,6 +253,12 @@ class RetainPtrCtorAdoptChecker
247253
enum class IsOwnedResult { Unknown, Skip, Owned, NotOwned };
248254
IsOwnedResult isOwned(const Expr *E) const {
249255
while (1) {
256+
if (auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
257+
if (unsigned SemanticExprCount = POE->getNumSemanticExprs()) {
258+
E = POE->getSemanticExpr(SemanticExprCount - 1);
259+
continue;
260+
}
261+
}
250262
if (isa<CXXNullPtrLiteralExpr>(E))
251263
return IsOwnedResult::NotOwned;
252264
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
@class NSString;
22
@class NSArray;
33
@class NSMutableArray;
4+
@class NSDictionary;
5+
@class NSMutableDictionary;
46
#define nil ((id)0)
57
#define CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T)))
68
#define CF_BRIDGED_MUTABLE_TYPE(T) __attribute__((objc_bridge_mutable(T)))
@@ -95,12 +97,14 @@ __attribute__((objc_root_class))
9597
- (NSEnumerator *)keyEnumerator;
9698
+ (id)dictionary;
9799
+ (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
100+
- (NSMutableDictionary *)mutableCopy;
98101
+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
99102
@end
100103

101104
@interface NSArray : NSObject <NSCopying, NSFastEnumeration>
102105
- (NSUInteger)count;
103106
- (NSEnumerator *)objectEnumerator;
107+
- (NSMutableArray *)mutableCopy;
104108
+ (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count;
105109
@end
106110

@@ -109,6 +113,7 @@ __attribute__((objc_root_class))
109113
- (NSString *)stringByAppendingString:(NSString *)aString;
110114
- ( const char *)UTF8String;
111115
- (id)initWithUTF8String:(const char *)nullTerminatedCString;
116+
- (NSString *)copy;
112117
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
113118
@end
114119

clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,19 @@ void create_member_init() {
9797
RetainPtr<id> return_bridge_cast() {
9898
return bridge_cast<CFArrayRef, NSArray>(create_cf_array());
9999
}
100+
101+
void mutable_copy_dictionary() {
102+
RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{
103+
@"Content-Type": @"text/html",
104+
}.mutableCopy);
105+
}
106+
107+
void mutable_copy_array() {
108+
RetainPtr<NSMutableArray> mutableArray = adoptNS(@[
109+
@"foo",
110+
].mutableCopy);
111+
}
112+
113+
void string_copy(NSString *str) {
114+
RetainPtr<NSString> copy = adoptNS(str.copy);
115+
}

clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,19 @@ void create_member_init() {
9797
RetainPtr<id> return_bridge_cast() {
9898
return bridge_cast<CFArrayRef, NSArray>(create_cf_array());
9999
}
100+
101+
void mutable_copy_dictionary() {
102+
RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{
103+
@"Content-Type": @"text/html",
104+
}.mutableCopy);
105+
}
106+
107+
void mutable_copy_array() {
108+
RetainPtr<NSMutableArray> mutableArray = adoptNS(@[
109+
@"foo",
110+
].mutableCopy);
111+
}
112+
113+
void string_copy(NSString *str) {
114+
RetainPtr<NSString> copy = adoptNS(str.copy);
115+
}

0 commit comments

Comments
 (0)