Skip to content

Commit af4aeb3

Browse files
authored
[RawPtrRefMemberChecker] Make RawPtrRefMemberChecker consistent with other checkers (#137559)
Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
1 parent e9193f5 commit af4aeb3

File tree

1 file changed

+45
-53
lines changed

1 file changed

+45
-53
lines changed

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

Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ class RawPtrRefMemberChecker
3838
RawPtrRefMemberChecker(const char *description)
3939
: Bug(this, description, "WebKit coding guidelines") {}
4040

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;
4442
virtual const char *typeName() const = 0;
4543
virtual const char *invariant() const = 0;
4644

@@ -93,22 +91,30 @@ class RawPtrRefMemberChecker
9391
if (!MemberType)
9492
continue;
9593

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);
109102
}
110103
}
111104

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+
112118
void visitObjCDecl(const ObjCContainerDecl *CD) const {
113119
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
114120
return;
@@ -138,19 +144,15 @@ class RawPtrRefMemberChecker
138144
const Type *IvarType = QT.getTypePtrOrNull();
139145
if (!IvarType)
140146
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);
154156
}
155157

156158
void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
@@ -161,19 +163,15 @@ class RawPtrRefMemberChecker
161163
const Type *PropType = QT.getTypePtrOrNull();
162164
if (!PropType)
163165
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);
177175
}
178176

179177
bool shouldSkipDecl(const RecordDecl *RD) const {
@@ -263,10 +261,8 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker {
263261
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
264262
"reference-countable type") {}
265263

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());
270266
}
271267

272268
const char *typeName() const final { return "ref-countable type"; }
@@ -282,10 +278,8 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker {
282278
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
283279
"checked-pointer capable type") {}
284280

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());
289283
}
290284

291285
const char *typeName() const final { return "CheckedPtr capable type"; }
@@ -304,9 +298,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
304298
RTC = RetainTypeChecker();
305299
}
306300

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 {
310302
return RTC->isUnretained(QT);
311303
}
312304

0 commit comments

Comments
 (0)