Skip to content

Commit 8441808

Browse files
committed
[WebKit checkers] Recognize NS_RETURNS_RETAINED and CF_RETURNS_RETAINED. (llvm#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 d9c829c commit 8441808

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
@@ -92,6 +92,13 @@ bool tryToFindPtrOrigin(
9292
continue;
9393
}
9494
if (auto *call = dyn_cast<CallExpr>(E)) {
95+
if (auto *Callee = call->getCalleeDecl()) {
96+
if (Callee->hasAttr<CFReturnsRetainedAttr>() ||
97+
Callee->hasAttr<NSReturnsRetainedAttr>()) {
98+
return callback(E, true);
99+
}
100+
}
101+
95102
if (auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
96103
if (auto *decl = memberCall->getMethodDecl()) {
97104
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
@@ -437,6 +437,32 @@ void use_const_local() {
437437

438438
} // namespace const_global
439439

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