Skip to content

Commit b4001f9

Browse files
committed
[alpha.webkit.webkit.RetainPtrCtorAdoptChecker] Add a new WebKit checker for correct use of RetainPtr, adoptNS, and adoptCF
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 b335d5a commit b4001f9

File tree

9 files changed

+680
-18
lines changed

9 files changed

+680
-18
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3713,6 +3713,26 @@ Here are some examples of situations that we warn about as they *might* be poten
37133713
NSObject* unretained = retained.get(); // warn
37143714
}
37153715
3716+
webkit.RetainPtrCtorAdoptChecker
3717+
""""""""""""""""""""""""""""""""
3718+
The goal of this rule is to make sure the constructor of RetinPtr as well as adoptNS and adoptCF are used correctly.
3719+
When creating a RetainPtr with +1 semantics, adoptNS or adoptCF should be used, and in +0 semantics, RetainPtr constructor should be used.
3720+
Warn otherwise.
3721+
3722+
These are examples of cases that we consider correct:
3723+
3724+
.. code-block:: cpp
3725+
3726+
RetainPtr ptr = adoptNS([[NSObject alloc] init]); // ok
3727+
RetainPtr ptr = CGImageGetColorSpace(image); // ok
3728+
3729+
Here are some examples of cases that we consider incorrect use of RetainPtr constructor and adoptCF
3730+
3731+
.. code-block:: cpp
3732+
3733+
RetainPtr ptr = [[NSObject alloc] init]; // warn
3734+
auto ptr = adoptCF(CGImageGetColorSpace(image)); // warn
3735+
37163736
Debug Checkers
37173737
---------------
37183738

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

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

1789+
def RetainPtrCtorAdoptChecker : Checker<"RetainPtrCtorAdoptChecker">,
1790+
HelpText<"Check for correct use of RetainPtr constructor, adoptNS, and adoptCF">,
1791+
Documentation<HasDocumentation>;
1792+
17891793
} // 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/UncountedLambdaCapturesChecker.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
@@ -225,15 +225,16 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
225225
return;
226226

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

235-
bool RetainTypeChecker::isUnretained(const QualType QT) {
236-
if (ento::cocoa::isCocoaObjectRef(QT) && !IsARCEnabled)
236+
bool RetainTypeChecker::isUnretained(const QualType QT, bool ignoreARC) {
237+
if (ento::cocoa::isCocoaObjectRef(QT) && (!IsARCEnabled || ignoreARC))
237238
return true;
238239
auto CanonicalType = QT.getCanonicalType();
239240
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)