Skip to content

Commit be9ca85

Browse files
authored
[alpha.webkit.webkit.RetainPtrCtorAdoptChecker] Add a new WebKit checker for correct use of RetainPtr, adoptNS, and adoptCF (#128679)
Add a new WebKit checker to validate the correct use of RetainPtr constructor as well as adoptNS and adoptCF functions. adoptNS and adoptCf are used for +1 semantics and RetainPtr constructor is used for +0 semantics.
1 parent 12fe5ae commit be9ca85

File tree

9 files changed

+642
-4
lines changed

9 files changed

+642
-4
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3779,6 +3779,26 @@ Here are some examples of situations that we warn about as they *might* be poten
37793779
NSObject* unretained = retained.get(); // warn
37803780
}
37813781
3782+
webkit.RetainPtrCtorAdoptChecker
3783+
""""""""""""""""""""""""""""""""
3784+
The goal of this rule is to make sure the constructor of RetainPtr as well as adoptNS and adoptCF are used correctly.
3785+
When creating a RetainPtr with +1 semantics, adoptNS or adoptCF should be used, and in +0 semantics, RetainPtr constructor should be used.
3786+
Warn otherwise.
3787+
3788+
These are examples of cases that we consider correct:
3789+
3790+
.. code-block:: cpp
3791+
3792+
RetainPtr ptr = adoptNS([[NSObject alloc] init]); // ok
3793+
RetainPtr ptr = CGImageGetColorSpace(image); // ok
3794+
3795+
Here are some examples of cases that we consider incorrect use of RetainPtr constructor and adoptCF
3796+
3797+
.. code-block:: cpp
3798+
3799+
RetainPtr ptr = [[NSObject alloc] init]; // warn
3800+
auto ptr = adoptCF(CGImageGetColorSpace(image)); // warn
3801+
37823802
Debug Checkers
37833803
---------------
37843804

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,4 +1801,8 @@ def UnretainedLocalVarsChecker : Checker<"UnretainedLocalVarsChecker">,
18011801
HelpText<"Check unretained local variables.">,
18021802
Documentation<HasDocumentation>;
18031803

1804+
def RetainPtrCtorAdoptChecker : Checker<"RetainPtrCtorAdoptChecker">,
1805+
HelpText<"Check for correct use of RetainPtr constructor, adoptNS, and adoptCF">,
1806+
Documentation<HasDocumentation>;
1807+
18041808
} // end alpha.webkit

clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ add_clang_library(clangStaticAnalyzerCheckers
133133
WebKit/MemoryUnsafeCastChecker.cpp
134134
WebKit/PtrTypesSemantics.cpp
135135
WebKit/RefCntblBaseVirtualDtorChecker.cpp
136+
WebKit/RetainPtrCtorAdoptChecker.cpp
136137
WebKit/RawPtrRefCallArgsChecker.cpp
137138
WebKit/RawPtrRefLambdaCapturesChecker.cpp
138139
WebKit/RawPtrRefLocalVarsChecker.cpp

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,16 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
226226
return;
227227

228228
for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
229-
if (Redecl->getAttr<ObjCBridgeAttr>()) {
229+
if (Redecl->getAttr<ObjCBridgeAttr>() ||
230+
Redecl->getAttr<ObjCBridgeMutableAttr>()) {
230231
CFPointees.insert(RT);
231232
return;
232233
}
233234
}
234235
}
235236

236-
bool RetainTypeChecker::isUnretained(const QualType QT) {
237-
if (ento::cocoa::isCocoaObjectRef(QT) && !IsARCEnabled)
237+
bool RetainTypeChecker::isUnretained(const QualType QT, bool ignoreARC) {
238+
if (ento::cocoa::isCocoaObjectRef(QT) && (!IsARCEnabled || ignoreARC))
238239
return true;
239240
auto CanonicalType = QT.getCanonicalType();
240241
auto PointeeType = CanonicalType->getPointeeType();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ class RetainTypeChecker {
7575
public:
7676
void visitTranslationUnitDecl(const TranslationUnitDecl *);
7777
void visitTypedef(const TypedefDecl *);
78-
bool isUnretained(const QualType);
78+
bool isUnretained(const QualType, bool ignoreARC = false);
79+
bool isARCEnabled() const { return IsARCEnabled; }
7980
};
8081

8182
/// \returns true if \p Class is NS or CF objects AND not retained, false if

0 commit comments

Comments
 (0)