Author: Ryosuke Niwa Date: 2025-04-09T10:33:08-07:00 New Revision: c8d49e9dd2e7e4c64a0a70bf05b0e6c83b04841a
URL: https://github.com/llvm/llvm-project/commit/c8d49e9dd2e7e4c64a0a70bf05b0e6c83b04841a DIFF: https://github.com/llvm/llvm-project/commit/c8d49e9dd2e7e4c64a0a70bf05b0e6c83b04841a.diff LOG: [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. Added: Modified: clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp clang/test/Analysis/Checkers/WebKit/objc-mock-types.h clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp index 4ce3262e90e13..1f9a4712cedf6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp @@ -202,6 +202,12 @@ class RetainPtrCtorAdoptChecker bool isAllocInit(const Expr *E) const { auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E); + if (auto *POE = dyn_cast<PseudoObjectExpr>(E)) { + if (unsigned ExprCount = POE->getNumSemanticExprs()) { + auto *Expr = POE->getSemanticExpr(ExprCount - 1)->IgnoreParenCasts(); + ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(Expr); + } + } if (!ObjCMsgExpr) return false; auto Selector = ObjCMsgExpr->getSelector(); @@ -247,6 +253,12 @@ class RetainPtrCtorAdoptChecker enum class IsOwnedResult { Unknown, Skip, Owned, NotOwned }; IsOwnedResult isOwned(const Expr *E) const { while (1) { + if (auto *POE = dyn_cast<PseudoObjectExpr>(E)) { + if (unsigned SemanticExprCount = POE->getNumSemanticExprs()) { + E = POE->getSemanticExpr(SemanticExprCount - 1); + continue; + } + } if (isa<CXXNullPtrLiteralExpr>(E)) return IsOwnedResult::NotOwned; if (auto *DRE = dyn_cast<DeclRefExpr>(E)) { diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h index 059a203e3b0d1..9eb63b4745b21 100644 --- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h @@ -1,6 +1,8 @@ @class NSString; @class NSArray; @class NSMutableArray; +@class NSDictionary; +@class NSMutableDictionary; #define nil ((id)0) #define CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T))) #define CF_BRIDGED_MUTABLE_TYPE(T) __attribute__((objc_bridge_mutable(T))) @@ -95,12 +97,14 @@ __attribute__((objc_root_class)) - (NSEnumerator *)keyEnumerator; + (id)dictionary; + (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key; +- (NSMutableDictionary *)mutableCopy; + (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; @end @interface NSArray : NSObject <NSCopying, NSFastEnumeration> - (NSUInteger)count; - (NSEnumerator *)objectEnumerator; +- (NSMutableArray *)mutableCopy; + (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count; @end @@ -109,6 +113,7 @@ __attribute__((objc_root_class)) - (NSString *)stringByAppendingString:(NSString *)aString; - ( const char *)UTF8String; - (id)initWithUTF8String:(const char *)nullTerminatedCString; +- (NSString *)copy; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; @end diff --git a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm index dd7208a534ea1..63383d4f49642 100644 --- a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm @@ -97,3 +97,19 @@ void create_member_init() { RetainPtr<id> return_bridge_cast() { return bridge_cast<CFArrayRef, NSArray>(create_cf_array()); } + +void mutable_copy_dictionary() { + RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{ + @"Content-Type": @"text/html", + }.mutableCopy); +} + +void mutable_copy_array() { + RetainPtr<NSMutableArray> mutableArray = adoptNS(@[ + @"foo", + ].mutableCopy); +} + +void string_copy(NSString *str) { + RetainPtr<NSString> copy = adoptNS(str.copy); +} diff --git a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm index 79e0bdb7c577b..e94b7511dee14 100644 --- a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm +++ b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm @@ -97,3 +97,19 @@ void create_member_init() { RetainPtr<id> return_bridge_cast() { return bridge_cast<CFArrayRef, NSArray>(create_cf_array()); } + +void mutable_copy_dictionary() { + RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{ + @"Content-Type": @"text/html", + }.mutableCopy); +} + +void mutable_copy_array() { + RetainPtr<NSMutableArray> mutableArray = adoptNS(@[ + @"foo", + ].mutableCopy); +} + +void string_copy(NSString *str) { + RetainPtr<NSString> copy = adoptNS(str.copy); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits