@@ -38,9 +38,7 @@ class RawPtrRefMemberChecker
38
38
RawPtrRefMemberChecker (const char *description)
39
39
: Bug(this , description, " WebKit coding guidelines" ) {}
40
40
41
- virtual std::optional<bool >
42
- isPtrCompatible (const clang::QualType,
43
- const clang::CXXRecordDecl *R) const = 0 ;
41
+ virtual std::optional<bool > isUnsafePtr (QualType) const = 0;
44
42
virtual const char *typeName () const = 0;
45
43
virtual const char *invariant () const = 0;
46
44
@@ -93,22 +91,30 @@ class RawPtrRefMemberChecker
93
91
if (!MemberType)
94
92
continue ;
95
93
96
- if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl ()) {
97
- std::optional<bool > IsCompatible = isPtrCompatible (QT, MemberCXXRD);
98
- if (IsCompatible && *IsCompatible)
99
- reportBug (Member, MemberType, MemberCXXRD, RD);
100
- } else {
101
- std::optional<bool > IsCompatible = isPtrCompatible (QT, nullptr );
102
- auto *PointeeType = MemberType->getPointeeType ().getTypePtrOrNull ();
103
- if (IsCompatible && *IsCompatible) {
104
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType ();
105
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
106
- reportBug (Member, MemberType, ObjCType->getDecl (), RD);
107
- }
108
- }
94
+ auto IsUnsafePtr = isUnsafePtr (QT);
95
+ if (!IsUnsafePtr || !*IsUnsafePtr)
96
+ continue ;
97
+
98
+ if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl ())
99
+ reportBug (Member, MemberType, MemberCXXRD, RD);
100
+ else if (auto *ObjCDecl = getObjCDecl (MemberType))
101
+ reportBug (Member, MemberType, ObjCDecl, RD);
109
102
}
110
103
}
111
104
105
+ ObjCInterfaceDecl *getObjCDecl (const Type *TypePtr) const {
106
+ auto *PointeeType = TypePtr->getPointeeType ().getTypePtrOrNull ();
107
+ if (!PointeeType)
108
+ return nullptr ;
109
+ auto *Desugared = PointeeType->getUnqualifiedDesugaredType ();
110
+ if (!Desugared)
111
+ return nullptr ;
112
+ auto *ObjCType = dyn_cast<ObjCInterfaceType>(Desugared);
113
+ if (!ObjCType)
114
+ return nullptr ;
115
+ return ObjCType->getDecl ();
116
+ }
117
+
112
118
void visitObjCDecl (const ObjCContainerDecl *CD) const {
113
119
if (BR->getSourceManager ().isInSystemHeader (CD->getLocation ()))
114
120
return ;
@@ -138,19 +144,15 @@ class RawPtrRefMemberChecker
138
144
const Type *IvarType = QT.getTypePtrOrNull ();
139
145
if (!IvarType)
140
146
return ;
141
- if (auto *IvarCXXRD = IvarType->getPointeeCXXRecordDecl ()) {
142
- std::optional<bool > IsCompatible = isPtrCompatible (QT, IvarCXXRD);
143
- if (IsCompatible && *IsCompatible)
144
- reportBug (Ivar, IvarType, IvarCXXRD, CD);
145
- } else {
146
- std::optional<bool > IsCompatible = isPtrCompatible (QT, nullptr );
147
- auto *PointeeType = IvarType->getPointeeType ().getTypePtrOrNull ();
148
- if (IsCompatible && *IsCompatible) {
149
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType ();
150
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
151
- reportBug (Ivar, IvarType, ObjCType->getDecl (), CD);
152
- }
153
- }
147
+
148
+ auto IsUnsafePtr = isUnsafePtr (QT);
149
+ if (!IsUnsafePtr || !*IsUnsafePtr)
150
+ return ;
151
+
152
+ if (auto *MemberCXXRD = IvarType->getPointeeCXXRecordDecl ())
153
+ reportBug (Ivar, IvarType, MemberCXXRD, CD);
154
+ else if (auto *ObjCDecl = getObjCDecl (IvarType))
155
+ reportBug (Ivar, IvarType, ObjCDecl, CD);
154
156
}
155
157
156
158
void visitObjCPropertyDecl (const ObjCContainerDecl *CD,
@@ -161,19 +163,15 @@ class RawPtrRefMemberChecker
161
163
const Type *PropType = QT.getTypePtrOrNull ();
162
164
if (!PropType)
163
165
return ;
164
- if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl ()) {
165
- std::optional<bool > IsCompatible = isPtrCompatible (QT, PropCXXRD);
166
- if (IsCompatible && *IsCompatible)
167
- reportBug (PD, PropType, PropCXXRD, CD);
168
- } else {
169
- std::optional<bool > IsCompatible = isPtrCompatible (QT, nullptr );
170
- auto *PointeeType = PropType->getPointeeType ().getTypePtrOrNull ();
171
- if (IsCompatible && *IsCompatible) {
172
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType ();
173
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
174
- reportBug (PD, PropType, ObjCType->getDecl (), CD);
175
- }
176
- }
166
+
167
+ auto IsUnsafePtr = isUnsafePtr (QT);
168
+ if (!IsUnsafePtr || !*IsUnsafePtr)
169
+ return ;
170
+
171
+ if (auto *MemberCXXRD = PropType->getPointeeCXXRecordDecl ())
172
+ reportBug (PD, PropType, MemberCXXRD, CD);
173
+ else if (auto *ObjCDecl = getObjCDecl (PropType))
174
+ reportBug (PD, PropType, ObjCDecl, CD);
177
175
}
178
176
179
177
bool shouldSkipDecl (const RecordDecl *RD) const {
@@ -263,10 +261,8 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker {
263
261
: RawPtrRefMemberChecker(" Member variable is a raw-pointer/reference to "
264
262
" reference-countable type" ) {}
265
263
266
- std::optional<bool >
267
- isPtrCompatible (const clang::QualType,
268
- const clang::CXXRecordDecl *R) const final {
269
- return R ? isRefCountable (R) : std::nullopt;
264
+ std::optional<bool > isUnsafePtr (QualType QT) const final {
265
+ return isUncountedPtr (QT.getCanonicalType ());
270
266
}
271
267
272
268
const char *typeName () const final { return " ref-countable type" ; }
@@ -282,10 +278,8 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker {
282
278
: RawPtrRefMemberChecker(" Member variable is a raw-pointer/reference to "
283
279
" checked-pointer capable type" ) {}
284
280
285
- std::optional<bool >
286
- isPtrCompatible (const clang::QualType,
287
- const clang::CXXRecordDecl *R) const final {
288
- return R ? isCheckedPtrCapable (R) : std::nullopt;
281
+ std::optional<bool > isUnsafePtr (QualType QT) const final {
282
+ return isUncheckedPtr (QT.getCanonicalType ());
289
283
}
290
284
291
285
const char *typeName () const final { return " CheckedPtr capable type" ; }
@@ -304,9 +298,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
304
298
RTC = RetainTypeChecker ();
305
299
}
306
300
307
- std::optional<bool >
308
- isPtrCompatible (const clang::QualType QT,
309
- const clang::CXXRecordDecl *) const final {
301
+ std::optional<bool > isUnsafePtr (QualType QT) const final {
310
302
return RTC->isUnretained (QT);
311
303
}
312
304
0 commit comments