diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index 478bd85177143..f43e5ac9af198 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -91,6 +91,13 @@ bool tryToFindPtrOrigin( continue; } if (auto *call = dyn_cast(E)) { + if (auto *Callee = call->getCalleeDecl()) { + if (Callee->hasAttr() || + Callee->hasAttr()) { + return callback(E, true); + } + } + if (auto *memberCall = dyn_cast(call)) { if (auto *decl = memberCall->getMethodDecl()) { std::optional IsGetterOfRefCt = isGetterOfSafePtr(decl); diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm index c69113c48806d..d1d2e511cad19 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm @@ -438,6 +438,32 @@ void use_const_local() { } // namespace const_global +namespace ns_retained_return_value { + +NSString *provideNS() NS_RETURNS_RETAINED; +CFDictionaryRef provideCF() CF_RETURNS_RETAINED; +void consumeNS(NSString *); +void consumeCF(CFDictionaryRef); + +void foo() { + consumeNS(provideNS()); + consumeCF(provideCF()); +} + +struct Base { + NSString *provideStr() NS_RETURNS_RETAINED; +}; + +struct Derived : Base { + void consumeStr(NSString *); + + void foo() { + consumeStr(provideStr()); + } +}; + +} // namespace ns_retained_return_value + @interface TestObject : NSObject - (void)doWork:(NSString *)msg, ...; - (void)doWorkOnSelf; diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm index 10f7c9acb7a3c..0ad8f707e254c 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm @@ -408,6 +408,21 @@ void use_const_local() { } // namespace const_global +namespace ns_retained_return_value { + +NSString *provideNS() NS_RETURNS_RETAINED; +CFDictionaryRef provideCF() CF_RETURNS_RETAINED; +void consumeNS(NSString *); +void consumeCF(CFDictionaryRef); + +unsigned foo() { + auto *string = provideNS(); + auto *dictionary = provideCF(); + return string.length + CFDictionaryGetCount(dictionary); +} + +} // namespace ns_retained_return_value + bool doMoreWorkOpaque(OtherObj*); SomeObj* provide();