Skip to content

Commit ac1511d

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

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

@@ -94,22 +92,30 @@ class RawPtrRefMemberChecker
9492
if (!MemberType)
9593
continue;
9694

97-
if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl()) {
98-
std::optional<bool> IsCompatible = isPtrCompatible(QT, MemberCXXRD);
99-
if (IsCompatible && *IsCompatible)
100-
reportBug(Member, MemberType, MemberCXXRD, RD);
101-
} else {
102-
std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
103-
auto *PointeeType = MemberType->getPointeeType().getTypePtrOrNull();
104-
if (IsCompatible && *IsCompatible) {
105-
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
106-
if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
107-
reportBug(Member, MemberType, ObjCType->getDecl(), RD);
108-
}
109-
}
95+
auto IsUnsafePtr = isUnsafePtr(QT);
96+
if (!IsUnsafePtr || !*IsUnsafePtr)
97+
continue;
98+
99+
if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl())
100+
reportBug(Member, MemberType, MemberCXXRD, RD);
101+
else if (auto *ObjCDecl = getObjCDecl(MemberType))
102+
reportBug(Member, MemberType, ObjCDecl, RD);
110103
}
111104
}
112105

106+
ObjCInterfaceDecl *getObjCDecl(const Type *TypePtr) const {
107+
auto *PointeeType = TypePtr->getPointeeType().getTypePtrOrNull();
108+
if (!PointeeType)
109+
return nullptr;
110+
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
111+
if (!Desugared)
112+
return nullptr;
113+
auto *ObjCType = dyn_cast<ObjCInterfaceType>(Desugared);
114+
if (!ObjCType)
115+
return nullptr;
116+
return ObjCType->getDecl();
117+
}
118+
113119
void visitObjCDecl(const ObjCContainerDecl *CD) const {
114120
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
115121
return;
@@ -139,19 +145,15 @@ class RawPtrRefMemberChecker
139145
const Type *IvarType = QT.getTypePtrOrNull();
140146
if (!IvarType)
141147
return;
142-
if (auto *IvarCXXRD = IvarType->getPointeeCXXRecordDecl()) {
143-
std::optional<bool> IsCompatible = isPtrCompatible(QT, IvarCXXRD);
144-
if (IsCompatible && *IsCompatible)
145-
reportBug(Ivar, IvarType, IvarCXXRD, CD);
146-
} else {
147-
std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
148-
auto *PointeeType = IvarType->getPointeeType().getTypePtrOrNull();
149-
if (IsCompatible && *IsCompatible) {
150-
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
151-
if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
152-
reportBug(Ivar, IvarType, ObjCType->getDecl(), CD);
153-
}
154-
}
148+
149+
auto IsUnsafePtr = isUnsafePtr(QT);
150+
if (!IsUnsafePtr || !*IsUnsafePtr)
151+
return;
152+
153+
if (auto *MemberCXXRD = IvarType->getPointeeCXXRecordDecl())
154+
reportBug(Ivar, IvarType, MemberCXXRD, CD);
155+
else if (auto *ObjCDecl = getObjCDecl(IvarType))
156+
reportBug(Ivar, IvarType, ObjCDecl, CD);
155157
}
156158

157159
void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
@@ -162,19 +164,15 @@ class RawPtrRefMemberChecker
162164
const Type *PropType = QT.getTypePtrOrNull();
163165
if (!PropType)
164166
return;
165-
if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl()) {
166-
std::optional<bool> IsCompatible = isPtrCompatible(QT, PropCXXRD);
167-
if (IsCompatible && *IsCompatible)
168-
reportBug(PD, PropType, PropCXXRD, CD);
169-
} else {
170-
std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
171-
auto *PointeeType = PropType->getPointeeType().getTypePtrOrNull();
172-
if (IsCompatible && *IsCompatible) {
173-
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
174-
if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
175-
reportBug(PD, PropType, ObjCType->getDecl(), CD);
176-
}
177-
}
167+
168+
auto IsUnsafePtr = isUnsafePtr(QT);
169+
if (!IsUnsafePtr || !*IsUnsafePtr)
170+
return;
171+
172+
if (auto *MemberCXXRD = PropType->getPointeeCXXRecordDecl())
173+
reportBug(PD, PropType, MemberCXXRD, CD);
174+
else if (auto *ObjCDecl = getObjCDecl(PropType))
175+
reportBug(PD, PropType, ObjCDecl, CD);
178176
}
179177

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

267-
std::optional<bool>
268-
isPtrCompatible(const clang::QualType,
269-
const clang::CXXRecordDecl *R) const final {
270-
return R ? isRefCountable(R) : std::nullopt;
265+
std::optional<bool> isUnsafePtr(QualType QT) const final {
266+
return isUncountedPtr(QT.getCanonicalType());
271267
}
272268

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

286-
std::optional<bool>
287-
isPtrCompatible(const clang::QualType,
288-
const clang::CXXRecordDecl *R) const final {
289-
return R ? isCheckedPtrCapable(R) : std::nullopt;
282+
std::optional<bool> isUnsafePtr(QualType QT) const final {
283+
return isUncheckedPtr(QT.getCanonicalType());
290284
}
291285

292286
const char *typeName() const final { return "CheckedPtr capable type"; }
@@ -305,9 +299,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
305299
RTC = RetainTypeChecker();
306300
}
307301

308-
std::optional<bool>
309-
isPtrCompatible(const clang::QualType QT,
310-
const clang::CXXRecordDecl *) const final {
302+
std::optional<bool> isUnsafePtr(QualType QT) const final {
311303
return RTC->isUnretained(QT);
312304
}
313305

0 commit comments

Comments
 (0)