Skip to content

Commit b64ed9d

Browse files
authored
[WebKit checkers] Recognize NS_RETURNS_RETAINED and CF_RETURNS_RETAINED. (#157629)
This PR adds the support for treating a function return value to be safe if the function is annotated with NS_RETURNS_RETAINED or CF_RETURNS_RETAINED.
1 parent 3097688 commit b64ed9d

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ bool tryToFindPtrOrigin(
9191
continue;
9292
}
9393
if (auto *call = dyn_cast<CallExpr>(E)) {
94+
if (auto *Callee = call->getCalleeDecl()) {
95+
if (Callee->hasAttr<CFReturnsRetainedAttr>() ||
96+
Callee->hasAttr<NSReturnsRetainedAttr>()) {
97+
return callback(E, true);
98+
}
99+
}
100+
94101
if (auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
95102
if (auto *decl = memberCall->getMethodDecl()) {
96103
std::optional<bool> IsGetterOfRefCt = isGetterOfSafePtr(decl);

clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,32 @@ void use_const_local() {
438438

439439
} // namespace const_global
440440

441+
namespace ns_retained_return_value {
442+
443+
NSString *provideNS() NS_RETURNS_RETAINED;
444+
CFDictionaryRef provideCF() CF_RETURNS_RETAINED;
445+
void consumeNS(NSString *);
446+
void consumeCF(CFDictionaryRef);
447+
448+
void foo() {
449+
consumeNS(provideNS());
450+
consumeCF(provideCF());
451+
}
452+
453+
struct Base {
454+
NSString *provideStr() NS_RETURNS_RETAINED;
455+
};
456+
457+
struct Derived : Base {
458+
void consumeStr(NSString *);
459+
460+
void foo() {
461+
consumeStr(provideStr());
462+
}
463+
};
464+
465+
} // namespace ns_retained_return_value
466+
441467
@interface TestObject : NSObject
442468
- (void)doWork:(NSString *)msg, ...;
443469
- (void)doWorkOnSelf;

clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,21 @@ void use_const_local() {
408408

409409
} // namespace const_global
410410

411+
namespace ns_retained_return_value {
412+
413+
NSString *provideNS() NS_RETURNS_RETAINED;
414+
CFDictionaryRef provideCF() CF_RETURNS_RETAINED;
415+
void consumeNS(NSString *);
416+
void consumeCF(CFDictionaryRef);
417+
418+
unsigned foo() {
419+
auto *string = provideNS();
420+
auto *dictionary = provideCF();
421+
return string.length + CFDictionaryGetCount(dictionary);
422+
}
423+
424+
} // namespace ns_retained_return_value
425+
411426
bool doMoreWorkOpaque(OtherObj*);
412427
SomeObj* provide();
413428

0 commit comments

Comments
 (0)