Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ bool tryToFindPtrOrigin(
continue;
}
if (auto *call = dyn_cast<CallExpr>(E)) {
if (auto *Callee = call->getCalleeDecl()) {
if (Callee->hasAttr<CFReturnsRetainedAttr>() ||
Callee->hasAttr<NSReturnsRetainedAttr>()) {
return callback(E, true);
}
}

if (auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
if (auto *decl = memberCall->getMethodDecl()) {
std::optional<bool> IsGetterOfRefCt = isGetterOfSafePtr(decl);
Expand Down
14 changes: 14 additions & 0 deletions clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,20 @@ 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());
}

} // namespace ns_retained_return_value

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain this works, but can we have a test case with inheritance (sub class calls provideNS defined in super class) for the sake of completion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean provideNS returns a subclass of a class consumeNS takes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or are you talking about adding a test case where provideNS is defined in a C++ class then a subclass of it calls consumeNS(provideNS()) in some member function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or are you talking about adding a test case where provideNS is defined in a C++ class then a subclass of it calls consumeNS(provideNS()) in some member function?

I was thinking of this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, added.

@interface TestObject : NSObject
- (void)doWork:(NSString *)msg, ...;
- (void)doWorkOnSelf;
Expand Down
15 changes: 15 additions & 0 deletions clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down