@@ -840,20 +840,27 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
840840const RefCountBug &
841841RetainCountChecker::errorKindToBugKind (RefVal::Kind ErrorKind,
842842 SymbolRef Sym) const {
843+ const RefCountFrontend &FE = getPreferredFrontend ();
844+
843845 switch (ErrorKind) {
844846 case RefVal::ErrorUseAfterRelease:
845- return * UseAfterRelease;
847+ return FE. UseAfterRelease ;
846848 case RefVal::ErrorReleaseNotOwned:
847- return * ReleaseNotOwned;
849+ return FE. ReleaseNotOwned ;
848850 case RefVal::ErrorDeallocNotOwned:
849851 if (Sym->getType ()->getPointeeCXXRecordDecl ())
850- return * FreeNotOwned;
851- return * DeallocNotOwned;
852+ return FE. FreeNotOwned ;
853+ return FE. DeallocNotOwned ;
852854 default :
853855 llvm_unreachable (" Unhandled error." );
854856 }
855857}
856858
859+ bool RetainCountChecker::isReleaseUnownedError (RefVal::Kind ErrorKind) const {
860+ return ErrorKind == RefVal::ErrorReleaseNotOwned ||
861+ ErrorKind == RefVal::ErrorDeallocNotOwned;
862+ }
863+
857864void RetainCountChecker::processNonLeakError (ProgramStateRef St,
858865 SourceRange ErrorRange,
859866 RefVal::Kind ErrorKind,
@@ -874,8 +881,8 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
874881 return ;
875882
876883 auto report = std::make_unique<RefCountReport>(
877- errorKindToBugKind (ErrorKind, Sym),
878- C. getASTContext (). getLangOpts (), N, Sym );
884+ errorKindToBugKind (ErrorKind, Sym), C. getASTContext (). getLangOpts (), N,
885+ Sym, /* isLeak= */ false , isReleaseUnownedError (ErrorKind) );
879886 report->addRange (ErrorRange);
880887 C.emitReport (std::move (report));
881888}
@@ -1090,8 +1097,8 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
10901097 ExplodedNode *N = C.addTransition (state, Pred);
10911098 if (N) {
10921099 const LangOptions &LOpts = C.getASTContext ().getLangOpts ();
1093- auto R =
1094- std::make_unique<RefLeakReport>(* LeakAtReturn, LOpts, N, Sym, C);
1100+ auto R = std::make_unique<RefLeakReport>(
1101+ getPreferredFrontend (). LeakAtReturn , LOpts, N, Sym, C);
10951102 C.emitReport (std::move (R));
10961103 }
10971104 return N;
@@ -1113,7 +1120,8 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
11131120 ExplodedNode *N = C.addTransition (state, Pred);
11141121 if (N) {
11151122 auto R = std::make_unique<RefCountReport>(
1116- *ReturnNotOwnedForOwned, C.getASTContext ().getLangOpts (), N, Sym);
1123+ getPreferredFrontend ().ReturnNotOwnedForOwned ,
1124+ C.getASTContext ().getLangOpts (), N, Sym);
11171125 C.emitReport (std::move (R));
11181126 }
11191127 return N;
@@ -1261,8 +1269,8 @@ ProgramStateRef RetainCountChecker::handleAutoreleaseCounts(
12611269 os << " has a +" << V.getCount () << " retain count" ;
12621270
12631271 const LangOptions &LOpts = Ctx.getASTContext ().getLangOpts ();
1264- auto R = std::make_unique<RefCountReport>(*OverAutorelease, LOpts, N, Sym,
1265- os.str ());
1272+ auto R = std::make_unique<RefCountReport>(
1273+ getPreferredFrontend (). OverAutorelease , LOpts, N, Sym, os.str ());
12661274 Ctx.emitReport (std::move (R));
12671275 }
12681276
@@ -1307,8 +1315,10 @@ RetainCountChecker::processLeaks(ProgramStateRef state,
13071315 const LangOptions &LOpts = Ctx.getASTContext ().getLangOpts ();
13081316
13091317 if (N) {
1318+ const RefCountFrontend &FE = getPreferredFrontend ();
1319+ const RefCountBug &BT = Pred ? FE.LeakWithinFunction : FE.LeakAtReturn ;
1320+
13101321 for (SymbolRef L : Leaked) {
1311- const RefCountBug &BT = Pred ? *LeakWithinFunction : *LeakAtReturn;
13121322 Ctx.emitReport (std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
13131323 }
13141324 }
@@ -1463,44 +1473,31 @@ std::unique_ptr<SimpleProgramPointTag> RetainCountChecker::DeallocSentTag;
14631473std::unique_ptr<SimpleProgramPointTag> RetainCountChecker::CastFailTag;
14641474
14651475void ento::registerRetainCountBase (CheckerManager &Mgr) {
1466- auto *Chk = Mgr.registerChecker <RetainCountChecker>();
1476+ auto *Chk = Mgr.getChecker <RetainCountChecker>();
14671477 Chk->DeallocSentTag = std::make_unique<SimpleProgramPointTag>(
14681478 " RetainCountChecker" , " DeallocSent" );
14691479 Chk->CastFailTag = std::make_unique<SimpleProgramPointTag>(
14701480 " RetainCountChecker" , " DynamicCastFail" );
14711481}
14721482
1473- bool ento::shouldRegisterRetainCountBase (const CheckerManager &mgr ) {
1483+ bool ento::shouldRegisterRetainCountBase (const CheckerManager &) {
14741484 return true ;
14751485}
1486+
14761487void ento::registerRetainCountChecker (CheckerManager &Mgr) {
14771488 auto *Chk = Mgr.getChecker <RetainCountChecker>();
1478- Chk->TrackObjCAndCFObjects = true ;
1489+ Chk->RetainCount . enable (Mgr) ;
14791490 Chk->TrackNSCFStartParam = Mgr.getAnalyzerOptions ().getCheckerBooleanOption (
14801491 Mgr.getCurrentCheckerName (), " TrackNSCFStartParam" );
1481-
1482- #define INIT_BUGTYPE (KIND ) \
1483- Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName (), \
1484- RefCountBug::KIND);
1485- // TODO: Ideally, we should have a checker for each of these bug types.
1486- INIT_BUGTYPE (UseAfterRelease)
1487- INIT_BUGTYPE (ReleaseNotOwned)
1488- INIT_BUGTYPE (DeallocNotOwned)
1489- INIT_BUGTYPE (FreeNotOwned)
1490- INIT_BUGTYPE (OverAutorelease)
1491- INIT_BUGTYPE (ReturnNotOwnedForOwned)
1492- INIT_BUGTYPE (LeakWithinFunction)
1493- INIT_BUGTYPE (LeakAtReturn)
1494- #undef INIT_BUGTYPE
14951492}
14961493
1497- bool ento::shouldRegisterRetainCountChecker (const CheckerManager &mgr ) {
1494+ bool ento::shouldRegisterRetainCountChecker (const CheckerManager &) {
14981495 return true ;
14991496}
15001497
15011498void ento::registerOSObjectRetainCountChecker (CheckerManager &Mgr) {
15021499 auto *Chk = Mgr.getChecker <RetainCountChecker>();
1503- Chk->TrackOSObjects = true ;
1500+ Chk->OSObjectRetainCount . enable (Mgr) ;
15041501
15051502 // FIXME: We want bug reports to always have the same checker name associated
15061503 // with them, yet here, if RetainCountChecker is disabled but
@@ -1511,21 +1508,8 @@ void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
15111508 // diagnostics, and **hidden checker options** with the fine-tuning of
15121509 // modeling. Following this logic, OSObjectRetainCountChecker should be the
15131510 // latter, but we can't just remove it for backward compatibility reasons.
1514- #define LAZY_INIT_BUGTYPE (KIND ) \
1515- if (!Chk->KIND ) \
1516- Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName (), \
1517- RefCountBug::KIND);
1518- LAZY_INIT_BUGTYPE (UseAfterRelease)
1519- LAZY_INIT_BUGTYPE (ReleaseNotOwned)
1520- LAZY_INIT_BUGTYPE (DeallocNotOwned)
1521- LAZY_INIT_BUGTYPE (FreeNotOwned)
1522- LAZY_INIT_BUGTYPE (OverAutorelease)
1523- LAZY_INIT_BUGTYPE (ReturnNotOwnedForOwned)
1524- LAZY_INIT_BUGTYPE (LeakWithinFunction)
1525- LAZY_INIT_BUGTYPE (LeakAtReturn)
1526- #undef LAZY_INIT_BUGTYPE
15271511}
15281512
1529- bool ento::shouldRegisterOSObjectRetainCountChecker (const CheckerManager &mgr ) {
1513+ bool ento::shouldRegisterOSObjectRetainCountChecker (const CheckerManager &) {
15301514 return true ;
15311515}
0 commit comments