Skip to content

Commit c7f0961

Browse files
committed
[alpha.webkit.UncountedCallArgsChecker] Allow protector functions in Objective-C++ (llvm#108184)
This PR fixes the bug that WebKit checkers didn't recognize the return value of an Objective-C++ selector which returns Ref or RefPtr to be safe.
1 parent 2fa4ba1 commit c7f0961

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ bool isReturnValueRefCounted(const clang::FunctionDecl *F) {
143143
return false;
144144
}
145145

146+
std::optional<bool> isUncounted(const QualType T) {
147+
if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T)) {
148+
if (auto *Decl = Subst->getAssociatedDecl()) {
149+
if (isRefType(safeGetName(Decl)))
150+
return false;
151+
}
152+
}
153+
return isUncounted(T->getAsCXXRecordDecl());
154+
}
155+
146156
std::optional<bool> isUncounted(const CXXRecordDecl* Class)
147157
{
148158
// Keep isRefCounted first as it's cheaper.

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class CXXMethodDecl;
2020
class CXXRecordDecl;
2121
class Decl;
2222
class FunctionDecl;
23+
class QualType;
2324
class Stmt;
2425
class Type;
2526

@@ -42,6 +43,10 @@ std::optional<bool> isRefCountable(const clang::CXXRecordDecl* Class);
4243
/// \returns true if \p Class is ref-counted, false if not.
4344
bool isRefCounted(const clang::CXXRecordDecl *Class);
4445

46+
/// \returns true if \p Class is ref-countable AND not ref-counted, false if
47+
/// not, std::nullopt if inconclusive.
48+
std::optional<bool> isUncounted(const clang::QualType T);
49+
4550
/// \returns true if \p Class is ref-countable AND not ref-counted, false if
4651
/// not, std::nullopt if inconclusive.
4752
std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class);

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ class UncountedCallArgsChecker
8787
}
8888
auto *E = MemberCallExpr->getImplicitObjectArgument();
8989
QualType ArgType = MemberCallExpr->getObjectType();
90-
std::optional<bool> IsUncounted =
91-
isUncounted(ArgType->getAsCXXRecordDecl());
90+
std::optional<bool> IsUncounted = isUncounted(ArgType);
9291
if (IsUncounted && *IsUncounted && !isPtrOriginSafe(E))
9392
reportBugOnThis(E);
9493
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
2+
// expected-no-diagnostics
3+
4+
#import "mock-types.h"
5+
#import "mock-system-header.h"
6+
#import "../../Inputs/system-header-simulator-for-objc-dealloc.h"
7+
8+
@interface Foo : NSObject
9+
10+
@property (nonatomic, readonly) RefPtr<RefCountable> countable;
11+
12+
- (void)execute;
13+
- (RefPtr<RefCountable>)_protectedRefCountable;
14+
@end
15+
16+
@implementation Foo
17+
18+
- (void)execute {
19+
self._protectedRefCountable->method();
20+
}
21+
22+
- (RefPtr<RefCountable>)_protectedRefCountable {
23+
return _countable;
24+
}
25+
26+
@end

0 commit comments

Comments
 (0)