aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorDonĂ¡t Nagy <donat.nagy@ericsson.com>2025-06-19 14:00:36 +0200
committerGitHub <noreply@github.com>2025-06-19 14:00:36 +0200
commitb73720cf6c5380854bf27d4453abf21cc87ae642 (patch)
treed48357a73ffd0e02716b8ac40c3d1a0bc5f85358 /clang/lib/StaticAnalyzer/Checkers
parente33f13ba4824d807e846e7783a48efd6c0bf58ee (diff)
downloadllvm-b73720cf6c5380854bf27d4453abf21cc87ae642.zip
llvm-b73720cf6c5380854bf27d4453abf21cc87ae642.tar.gz
llvm-b73720cf6c5380854bf27d4453abf21cc87ae642.tar.bz2
[analyzer] Conversion to CheckerFamily: DynamicTypePropagation (#144735)
This commit converts the class DynamicTypePropagation to a very simple checker family, which has only one checker frontend -- but also supports enabling the backend ("modeling checker") without the frontend. As a tangentially related change, this commit adds the backend of DynamicTypePropagation as a dependency of alpha.core.DynamicTypeChecker in Checkers.td, because the header comment of DynamicTypeChecker.cpp claims that it depends on DynamicTypePropagation and the source code seems to confirm this. (The lack of this dependency relationship didn't cause problems, because 'core.DynamicTypePropagation' is in the group 'core', so it is practically always active. However, explicitly declaring the dependency clarifies the fact that the separate existence of the modeling checker is warranted.)
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp55
1 files changed, 26 insertions, 29 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 344be0b..4982cd59 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -49,15 +49,19 @@ REGISTER_MAP_WITH_PROGRAMSTATE(MostSpecializedTypeArgsMap, SymbolRef,
const ObjCObjectPointerType *)
namespace {
-class DynamicTypePropagation:
- public Checker< check::PreCall,
- check::PostCall,
- check::DeadSymbols,
- check::PostStmt<CastExpr>,
- check::PostStmt<CXXNewExpr>,
- check::PreObjCMessage,
- check::PostObjCMessage > {
+class DynamicTypePropagation
+ : public CheckerFamily<check::PreCall, check::PostCall, check::DeadSymbols,
+ check::PostStmt<CastExpr>,
+ check::PostStmt<CXXNewExpr>, check::PreObjCMessage,
+ check::PostObjCMessage> {
+public:
+ // This checker family implements only one frontend, but -- unlike a simple
+ // Checker -- its backend can be enabled (by the checker DynamicTypeChecker
+ // which depends on it) without enabling the frontend.
+ CheckerFrontendWithBugType ObjCGenericsChecker{
+ "Generics", categories::CoreFoundationObjectiveC};
+private:
/// Return a better dynamic type if one can be derived from the cast.
const ObjCObjectPointerType *getBetterObjCType(const Expr *CastE,
CheckerContext &C) const;
@@ -66,13 +70,6 @@ class DynamicTypePropagation:
ProgramStateRef &State,
CheckerContext &C) const;
- mutable std::unique_ptr<BugType> ObjCGenericsBugType;
- void initBugType() const {
- if (!ObjCGenericsBugType)
- ObjCGenericsBugType.reset(new BugType(
- GenericCheckName, "Generics", categories::CoreFoundationObjectiveC));
- }
-
class GenericsBugVisitor : public BugReporterVisitor {
public:
GenericsBugVisitor(SymbolRef S) : Sym(S) {}
@@ -106,9 +103,8 @@ public:
void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
- /// This value is set to true, when the Generics checker is turned on.
- bool CheckGenerics = false;
- CheckerNameRef GenericCheckName;
+ /// Identifies this checker family for debugging purposes.
+ StringRef getDebugTag() const override { return "DynamicTypePropagation"; }
};
bool isObjCClassType(QualType Type) {
@@ -1026,10 +1022,9 @@ void DynamicTypePropagation::reportGenericsBug(
const ObjCObjectPointerType *From, const ObjCObjectPointerType *To,
ExplodedNode *N, SymbolRef Sym, CheckerContext &C,
const Stmt *ReportedNode) const {
- if (!CheckGenerics)
+ if (!ObjCGenericsChecker.isEnabled())
return;
- initBugType();
SmallString<192> Buf;
llvm::raw_svector_ostream OS(Buf);
OS << "Conversion from value of type '";
@@ -1037,7 +1032,7 @@ void DynamicTypePropagation::reportGenericsBug(
OS << "' to incompatible type '";
QualType::print(To, Qualifiers(), OS, C.getLangOpts(), llvm::Twine());
OS << "'";
- auto R = std::make_unique<PathSensitiveBugReport>(*ObjCGenericsBugType,
+ auto R = std::make_unique<PathSensitiveBugReport>(ObjCGenericsChecker,
OS.str(), N);
R->markInteresting(Sym);
R->addVisitor(std::make_unique<GenericsBugVisitor>(Sym));
@@ -1102,20 +1097,22 @@ PathDiagnosticPieceRef DynamicTypePropagation::GenericsBugVisitor::VisitNode(
}
/// Register checkers.
-void ento::registerObjCGenericsChecker(CheckerManager &mgr) {
- DynamicTypePropagation *checker = mgr.getChecker<DynamicTypePropagation>();
- checker->CheckGenerics = true;
- checker->GenericCheckName = mgr.getCurrentCheckerName();
+void ento::registerObjCGenericsChecker(CheckerManager &Mgr) {
+ Mgr.getChecker<DynamicTypePropagation>()->ObjCGenericsChecker.enable(Mgr);
}
-bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &mgr) {
+bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &) {
return true;
}
-void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
- mgr.registerChecker<DynamicTypePropagation>();
+void ento::registerDynamicTypePropagation(CheckerManager &Mgr) {
+ // The checker 'core.DynamicTypeChecker' relies on the modeling implemented
+ // in the class 'DynamicTypePropagation', so this "modeling checker" can
+ // register the 'DynamicTypePropagation' backend for its callbacks without
+ // enabling its frontend.
+ Mgr.getChecker<DynamicTypePropagation>();
}
-bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &mgr) {
+bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &) {
return true;
}