@@ -49,15 +49,19 @@ REGISTER_MAP_WITH_PROGRAMSTATE(MostSpecializedTypeArgsMap, SymbolRef,
49
49
const ObjCObjectPointerType *)
50
50
51
51
namespace {
52
- class DynamicTypePropagation :
53
- public Checker< check::PreCall,
54
- check::PostCall,
55
- check::DeadSymbols,
56
- check::PostStmt<CastExpr>,
57
- check::PostStmt<CXXNewExpr>,
58
- check::PreObjCMessage,
59
- check::PostObjCMessage > {
52
+ class DynamicTypePropagation
53
+ : public CheckerFamily<check::PreCall, check::PostCall, check::DeadSymbols,
54
+ check::PostStmt<CastExpr>,
55
+ check::PostStmt<CXXNewExpr>, check::PreObjCMessage,
56
+ check::PostObjCMessage> {
57
+ public:
58
+ // This checker family implements only one frontend, but -- unlike a simple
59
+ // Checker -- its backend can be enabled (by the checker DynamicTypeChecker
60
+ // which depends on it) without enabling the frontend.
61
+ CheckerFrontendWithBugType ObjCGenericsChecker{
62
+ " Generics" , categories::CoreFoundationObjectiveC};
60
63
64
+ private:
61
65
// / Return a better dynamic type if one can be derived from the cast.
62
66
const ObjCObjectPointerType *getBetterObjCType (const Expr *CastE,
63
67
CheckerContext &C) const ;
@@ -66,13 +70,6 @@ class DynamicTypePropagation:
66
70
ProgramStateRef &State,
67
71
CheckerContext &C) const ;
68
72
69
- mutable std::unique_ptr<BugType> ObjCGenericsBugType;
70
- void initBugType () const {
71
- if (!ObjCGenericsBugType)
72
- ObjCGenericsBugType.reset (new BugType (
73
- GenericCheckName, " Generics" , categories::CoreFoundationObjectiveC));
74
- }
75
-
76
73
class GenericsBugVisitor : public BugReporterVisitor {
77
74
public:
78
75
GenericsBugVisitor (SymbolRef S) : Sym(S) {}
@@ -106,9 +103,8 @@ class DynamicTypePropagation:
106
103
void checkPreObjCMessage (const ObjCMethodCall &M, CheckerContext &C) const ;
107
104
void checkPostObjCMessage (const ObjCMethodCall &M, CheckerContext &C) const ;
108
105
109
- // / This value is set to true, when the Generics checker is turned on.
110
- bool CheckGenerics = false ;
111
- CheckerNameRef GenericCheckName;
106
+ // / Identifies this checker family for debugging purposes.
107
+ StringRef getDebugTag () const override { return " DynamicTypePropagation" ; }
112
108
};
113
109
114
110
bool isObjCClassType (QualType Type) {
@@ -1026,18 +1022,17 @@ void DynamicTypePropagation::reportGenericsBug(
1026
1022
const ObjCObjectPointerType *From, const ObjCObjectPointerType *To,
1027
1023
ExplodedNode *N, SymbolRef Sym, CheckerContext &C,
1028
1024
const Stmt *ReportedNode) const {
1029
- if (!CheckGenerics )
1025
+ if (!ObjCGenericsChecker. isEnabled () )
1030
1026
return ;
1031
1027
1032
- initBugType ();
1033
1028
SmallString<192 > Buf;
1034
1029
llvm::raw_svector_ostream OS (Buf);
1035
1030
OS << " Conversion from value of type '" ;
1036
1031
QualType::print (From, Qualifiers (), OS, C.getLangOpts (), llvm::Twine ());
1037
1032
OS << " ' to incompatible type '" ;
1038
1033
QualType::print (To, Qualifiers (), OS, C.getLangOpts (), llvm::Twine ());
1039
1034
OS << " '" ;
1040
- auto R = std::make_unique<PathSensitiveBugReport>(*ObjCGenericsBugType ,
1035
+ auto R = std::make_unique<PathSensitiveBugReport>(ObjCGenericsChecker ,
1041
1036
OS.str (), N);
1042
1037
R->markInteresting (Sym);
1043
1038
R->addVisitor (std::make_unique<GenericsBugVisitor>(Sym));
@@ -1102,20 +1097,22 @@ PathDiagnosticPieceRef DynamicTypePropagation::GenericsBugVisitor::VisitNode(
1102
1097
}
1103
1098
1104
1099
// / Register checkers.
1105
- void ento::registerObjCGenericsChecker (CheckerManager &mgr) {
1106
- DynamicTypePropagation *checker = mgr.getChecker <DynamicTypePropagation>();
1107
- checker->CheckGenerics = true ;
1108
- checker->GenericCheckName = mgr.getCurrentCheckerName ();
1100
+ void ento::registerObjCGenericsChecker (CheckerManager &Mgr) {
1101
+ Mgr.getChecker <DynamicTypePropagation>()->ObjCGenericsChecker .enable (Mgr);
1109
1102
}
1110
1103
1111
- bool ento::shouldRegisterObjCGenericsChecker (const CheckerManager &mgr ) {
1104
+ bool ento::shouldRegisterObjCGenericsChecker (const CheckerManager &) {
1112
1105
return true ;
1113
1106
}
1114
1107
1115
- void ento::registerDynamicTypePropagation (CheckerManager &mgr) {
1116
- mgr.registerChecker <DynamicTypePropagation>();
1108
+ void ento::registerDynamicTypePropagation (CheckerManager &Mgr) {
1109
+ // The checker 'core.DynamicTypeChecker' relies on the modeling implemented
1110
+ // in the class 'DynamicTypePropagation', so this "modeling checker" can
1111
+ // register the 'DynamicTypePropagation' backend for its callbacks without
1112
+ // enabling its frontend.
1113
+ Mgr.getChecker <DynamicTypePropagation>();
1117
1114
}
1118
1115
1119
- bool ento::shouldRegisterDynamicTypePropagation (const CheckerManager &mgr ) {
1116
+ bool ento::shouldRegisterDynamicTypePropagation (const CheckerManager &) {
1120
1117
return true ;
1121
1118
}
0 commit comments