Skip to content

Commit 2ab2f23

Browse files
committed
[alpha.webkit.UncountedCallArgsChecker] Add support for Objective-C++ property access (llvm#108669)
Treat a function call or property access via a Objective-C++ selector which returns a Ref/RefPtr as safe.
1 parent 1359bad commit 2ab2f23

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "clang/AST/Decl.h"
1313
#include "clang/AST/DeclCXX.h"
1414
#include "clang/AST/ExprCXX.h"
15+
#include "clang/AST/ExprObjC.h"
1516
#include <optional>
1617

1718
namespace clang {
@@ -35,6 +36,12 @@ bool tryToFindPtrOrigin(
3536
break;
3637
}
3738
}
39+
if (auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
40+
if (auto *RF = POE->getResultExpr()) {
41+
E = RF;
42+
continue;
43+
}
44+
}
3845
if (auto *tempExpr = dyn_cast<ParenExpr>(E)) {
3946
E = tempExpr->getSubExpr();
4047
continue;
@@ -89,7 +96,7 @@ bool tryToFindPtrOrigin(
8996
continue;
9097
}
9198

92-
if (isReturnValueRefCounted(callee))
99+
if (isRefType(callee->getReturnType()))
93100
return callback(E, true);
94101

95102
if (isSingleton(callee))
@@ -101,6 +108,12 @@ bool tryToFindPtrOrigin(
101108
}
102109
}
103110
}
111+
if (auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E)) {
112+
if (auto *Method = ObjCMsgExpr->getMethodDecl()) {
113+
if (isRefType(Method->getReturnType()))
114+
return callback(E, true);
115+
}
116+
}
104117
if (auto *unaryOp = dyn_cast<UnaryOperator>(E)) {
105118
// FIXME: Currently accepts ANY unary operator. Is it OK?
106119
E = unaryOp->getSubExpr();

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,8 @@ bool isCtorOfRefCounted(const clang::FunctionDecl *F) {
123123
|| FunctionName == "Identifier";
124124
}
125125

126-
bool isReturnValueRefCounted(const clang::FunctionDecl *F) {
127-
assert(F);
128-
QualType type = F->getReturnType();
126+
bool isRefType(const clang::QualType T) {
127+
QualType type = T;
129128
while (!type.isNull()) {
130129
if (auto *elaboratedT = type->getAs<ElaboratedType>()) {
131130
type = elaboratedT->desugar();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ bool isRefType(const std::string &Name);
6262
/// false if not.
6363
bool isCtorOfRefCounted(const clang::FunctionDecl *F);
6464

65-
/// \returns true if \p F returns a ref-counted object, false if not.
66-
bool isReturnValueRefCounted(const clang::FunctionDecl *F);
65+
/// \returns true if \p T is RefPtr, Ref, or its variant, false if not.
66+
bool isRefType(const clang::QualType T);
6767

6868
/// \returns true if \p M is getter of a ref-counted class, false if not.
6969
std::optional<bool> isGetterOfRefCounted(const clang::CXXMethodDecl* Method);

clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,20 @@ - (void)execute {
2424
}
2525

2626
@end
27+
28+
class RefCountedObject {
29+
public:
30+
void ref() const;
31+
void deref() const;
32+
Ref<RefCountedObject> copy() const;
33+
};
34+
35+
@interface WrapperObj : NSObject
36+
37+
- (Ref<RefCountedObject>)_protectedWebExtensionControllerConfiguration;
38+
39+
@end
40+
41+
static void foo(WrapperObj *configuration) {
42+
configuration._protectedWebExtensionControllerConfiguration->copy();
43+
}

0 commit comments

Comments
 (0)