-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RawPtrRefMemberChecker] Make RawPtrRefMemberChecker consistent with other checkers #137559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RawPtrRefMemberChecker] Make RawPtrRefMemberChecker consistent with other checkers #137559
Conversation
…other checkers Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Ryosuke Niwa (rniwa) ChangesRefactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible. Full diff: https://github.com/llvm/llvm-project/pull/137559.diff 1 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index 10b9749319a57..209073e3ccc3a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -38,9 +38,7 @@ class RawPtrRefMemberChecker
RawPtrRefMemberChecker(const char *description)
: Bug(this, description, "WebKit coding guidelines") {}
- virtual std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const = 0;
+ virtual std::optional<bool> isUnsafePtr(QualType) const = 0;
virtual const char *typeName() const = 0;
virtual const char *invariant() const = 0;
@@ -93,22 +91,30 @@ class RawPtrRefMemberChecker
if (!MemberType)
continue;
- if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, MemberCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(Member, MemberType, MemberCXXRD, RD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = MemberType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(Member, MemberType, ObjCType->getDecl(), RD);
- }
- }
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ continue;
+
+ if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl())
+ reportBug(Member, MemberType, MemberCXXRD, RD);
+ else if (auto* ObjCDecl = getObjCDecl(MemberType))
+ reportBug(Member, MemberType, ObjCDecl, RD);
}
}
+ ObjCInterfaceDecl* getObjCDecl(const Type *TypePtr) const {
+ auto *PointeeType = TypePtr->getPointeeType().getTypePtrOrNull();
+ if (!PointeeType)
+ return nullptr;
+ auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
+ if (!Desugared)
+ return nullptr;
+ auto *ObjCType = dyn_cast<ObjCInterfaceType>(Desugared);
+ if (!ObjCType)
+ return nullptr;
+ return ObjCType->getDecl();
+ }
+
void visitObjCDecl(const ObjCContainerDecl *CD) const {
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
return;
@@ -138,19 +144,15 @@ class RawPtrRefMemberChecker
const Type *IvarType = QT.getTypePtrOrNull();
if (!IvarType)
return;
- if (auto *IvarCXXRD = IvarType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, IvarCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(Ivar, IvarType, IvarCXXRD, CD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = IvarType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(Ivar, IvarType, ObjCType->getDecl(), CD);
- }
- }
+
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ return;
+
+ if (auto *MemberCXXRD = IvarType->getPointeeCXXRecordDecl())
+ reportBug(Ivar, IvarType, MemberCXXRD, CD);
+ else if (auto* ObjCDecl = getObjCDecl(IvarType))
+ reportBug(Ivar, IvarType, ObjCDecl, CD);
}
void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
@@ -161,19 +163,15 @@ class RawPtrRefMemberChecker
const Type *PropType = QT.getTypePtrOrNull();
if (!PropType)
return;
- if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, PropCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(PD, PropType, PropCXXRD, CD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = PropType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(PD, PropType, ObjCType->getDecl(), CD);
- }
- }
+
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ return;
+
+ if (auto *MemberCXXRD = PropType->getPointeeCXXRecordDecl())
+ reportBug(PD, PropType, MemberCXXRD, CD);
+ else if (auto* ObjCDecl = getObjCDecl(PropType))
+ reportBug(PD, PropType, ObjCDecl, CD);
}
bool shouldSkipDecl(const RecordDecl *RD) const {
@@ -263,10 +261,8 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker {
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
"reference-countable type") {}
- std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const final {
- return R ? isRefCountable(R) : std::nullopt;
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
+ return isUncountedPtr(QT.getCanonicalType());
}
const char *typeName() const final { return "ref-countable type"; }
@@ -282,10 +278,8 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker {
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
"checked-pointer capable type") {}
- std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const final {
- return R ? isCheckedPtrCapable(R) : std::nullopt;
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
+ return isUncheckedPtr(QT.getCanonicalType());
}
const char *typeName() const final { return "CheckedPtr capable type"; }
@@ -304,9 +298,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
RTC = RetainTypeChecker();
}
- std::optional<bool>
- isPtrCompatible(const clang::QualType QT,
- const clang::CXXRecordDecl *) const final {
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
return RTC->isUnretained(QT);
}
|
@llvm/pr-subscribers-clang Author: Ryosuke Niwa (rniwa) ChangesRefactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible. Full diff: https://github.com/llvm/llvm-project/pull/137559.diff 1 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
index 10b9749319a57..209073e3ccc3a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp
@@ -38,9 +38,7 @@ class RawPtrRefMemberChecker
RawPtrRefMemberChecker(const char *description)
: Bug(this, description, "WebKit coding guidelines") {}
- virtual std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const = 0;
+ virtual std::optional<bool> isUnsafePtr(QualType) const = 0;
virtual const char *typeName() const = 0;
virtual const char *invariant() const = 0;
@@ -93,22 +91,30 @@ class RawPtrRefMemberChecker
if (!MemberType)
continue;
- if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, MemberCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(Member, MemberType, MemberCXXRD, RD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = MemberType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(Member, MemberType, ObjCType->getDecl(), RD);
- }
- }
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ continue;
+
+ if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl())
+ reportBug(Member, MemberType, MemberCXXRD, RD);
+ else if (auto* ObjCDecl = getObjCDecl(MemberType))
+ reportBug(Member, MemberType, ObjCDecl, RD);
}
}
+ ObjCInterfaceDecl* getObjCDecl(const Type *TypePtr) const {
+ auto *PointeeType = TypePtr->getPointeeType().getTypePtrOrNull();
+ if (!PointeeType)
+ return nullptr;
+ auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
+ if (!Desugared)
+ return nullptr;
+ auto *ObjCType = dyn_cast<ObjCInterfaceType>(Desugared);
+ if (!ObjCType)
+ return nullptr;
+ return ObjCType->getDecl();
+ }
+
void visitObjCDecl(const ObjCContainerDecl *CD) const {
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
return;
@@ -138,19 +144,15 @@ class RawPtrRefMemberChecker
const Type *IvarType = QT.getTypePtrOrNull();
if (!IvarType)
return;
- if (auto *IvarCXXRD = IvarType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, IvarCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(Ivar, IvarType, IvarCXXRD, CD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = IvarType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(Ivar, IvarType, ObjCType->getDecl(), CD);
- }
- }
+
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ return;
+
+ if (auto *MemberCXXRD = IvarType->getPointeeCXXRecordDecl())
+ reportBug(Ivar, IvarType, MemberCXXRD, CD);
+ else if (auto* ObjCDecl = getObjCDecl(IvarType))
+ reportBug(Ivar, IvarType, ObjCDecl, CD);
}
void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
@@ -161,19 +163,15 @@ class RawPtrRefMemberChecker
const Type *PropType = QT.getTypePtrOrNull();
if (!PropType)
return;
- if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl()) {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, PropCXXRD);
- if (IsCompatible && *IsCompatible)
- reportBug(PD, PropType, PropCXXRD, CD);
- } else {
- std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
- auto *PointeeType = PropType->getPointeeType().getTypePtrOrNull();
- if (IsCompatible && *IsCompatible) {
- auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
- if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
- reportBug(PD, PropType, ObjCType->getDecl(), CD);
- }
- }
+
+ auto IsUnsafePtr = isUnsafePtr(QT);
+ if (!IsUnsafePtr || !*IsUnsafePtr)
+ return;
+
+ if (auto *MemberCXXRD = PropType->getPointeeCXXRecordDecl())
+ reportBug(PD, PropType, MemberCXXRD, CD);
+ else if (auto* ObjCDecl = getObjCDecl(PropType))
+ reportBug(PD, PropType, ObjCDecl, CD);
}
bool shouldSkipDecl(const RecordDecl *RD) const {
@@ -263,10 +261,8 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker {
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
"reference-countable type") {}
- std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const final {
- return R ? isRefCountable(R) : std::nullopt;
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
+ return isUncountedPtr(QT.getCanonicalType());
}
const char *typeName() const final { return "ref-countable type"; }
@@ -282,10 +278,8 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker {
: RawPtrRefMemberChecker("Member variable is a raw-pointer/reference to "
"checked-pointer capable type") {}
- std::optional<bool>
- isPtrCompatible(const clang::QualType,
- const clang::CXXRecordDecl *R) const final {
- return R ? isCheckedPtrCapable(R) : std::nullopt;
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
+ return isUncheckedPtr(QT.getCanonicalType());
}
const char *typeName() const final { return "CheckedPtr capable type"; }
@@ -304,9 +298,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
RTC = RetainTypeChecker();
}
- std::optional<bool>
- isPtrCompatible(const clang::QualType QT,
- const clang::CXXRecordDecl *) const final {
+ std::optional<bool> isUnsafePtr(QualType QT) const final {
return RTC->isUnretained(QT);
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thanks for the review! |
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
…other checkers (llvm#137559) Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.
Refactor RawPtrRefMemberChecker so that each subclass override isUnsafePtr like other WebKit checkers instead of overriding isPtrCompatible.