@@ -99,7 +99,7 @@ class NilArgChecker : public Checker<check::PreObjCMessage,
9999 check::PostStmt<ObjCDictionaryLiteral>,
100100 check::PostStmt<ObjCArrayLiteral>,
101101 EventDispatcher<ImplicitNullDerefEvent>> {
102- mutable std::unique_ptr< APIMisuse> BT;
102+ const APIMisuse BT{ this , " nil argument " } ;
103103
104104 mutable llvm::SmallDenseMap<Selector, unsigned , 16 > StringSelectors;
105105 mutable Selector ArrayWithObjectSel;
@@ -218,10 +218,7 @@ void NilArgChecker::generateBugReport(ExplodedNode *N,
218218 SourceRange Range,
219219 const Expr *E,
220220 CheckerContext &C) const {
221- if (!BT)
222- BT.reset (new APIMisuse (this , " nil argument" ));
223-
224- auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
221+ auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
225222 R->addRange (Range);
226223 bugreporter::trackExpressionValue (N, E, *R);
227224 C.emitReport (std::move (R));
@@ -350,7 +347,7 @@ void NilArgChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
350347
351348namespace {
352349class CFNumberChecker : public Checker < check::PreStmt<CallExpr> > {
353- mutable std::unique_ptr< APIMisuse> BT;
350+ const APIMisuse BT{ this , " Bad use of CFNumber APIs " } ;
354351 mutable IdentifierInfo *ICreate = nullptr , *IGetValue = nullptr ;
355352public:
356353 CFNumberChecker () = default ;
@@ -524,10 +521,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE,
524521 << " bits of the integer value will be "
525522 << (isCreate ? " lost." : " garbage." );
526523
527- if (!BT)
528- BT.reset (new APIMisuse (this , " Bad use of CFNumber APIs" ));
529-
530- auto report = std::make_unique<PathSensitiveBugReport>(*BT, os.str (), N);
524+ auto report = std::make_unique<PathSensitiveBugReport>(BT, os.str (), N);
531525 report->addRange (CE->getArg (2 )->getSourceRange ());
532526 C.emitReport (std::move (report));
533527 }
@@ -539,7 +533,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE,
539533
540534namespace {
541535class CFRetainReleaseChecker : public Checker <check::PreCall> {
542- mutable APIMisuse BT{this , " null passed to CF memory management function" };
536+ const APIMisuse BT{this , " null passed to CF memory management function" };
543537 const CallDescriptionSet ModelledCalls = {
544538 {CDM::CLibrary, {" CFRetain" }, 1 },
545539 {CDM::CLibrary, {" CFRelease" }, 1 },
@@ -600,7 +594,8 @@ class ClassReleaseChecker : public Checker<check::PreObjCMessage> {
600594 mutable Selector retainS;
601595 mutable Selector autoreleaseS;
602596 mutable Selector drainS;
603- mutable std::unique_ptr<BugType> BT;
597+ const APIMisuse BT{
598+ this , " message incorrectly sent to class instead of class instance" };
604599
605600public:
606601 void checkPreObjCMessage (const ObjCMethodCall &msg, CheckerContext &C) const ;
@@ -609,10 +604,7 @@ class ClassReleaseChecker : public Checker<check::PreObjCMessage> {
609604
610605void ClassReleaseChecker::checkPreObjCMessage (const ObjCMethodCall &msg,
611606 CheckerContext &C) const {
612- if (!BT) {
613- BT.reset (new APIMisuse (
614- this , " message incorrectly sent to class instead of class instance" ));
615-
607+ if (releaseS.isNull ()) {
616608 ASTContext &Ctx = C.getASTContext ();
617609 releaseS = GetNullarySelector (" release" , Ctx);
618610 retainS = GetNullarySelector (" retain" , Ctx);
@@ -639,7 +631,7 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
639631 " of class '" << Class->getName ()
640632 << " ' and not the class directly" ;
641633
642- auto report = std::make_unique<PathSensitiveBugReport>(* BT, os.str (), N);
634+ auto report = std::make_unique<PathSensitiveBugReport>(BT, os.str (), N);
643635 report->addRange (msg.getSourceRange ());
644636 C.emitReport (std::move (report));
645637 }
@@ -658,7 +650,8 @@ class VariadicMethodTypeChecker : public Checker<check::PreObjCMessage> {
658650 mutable Selector orderedSetWithObjectsS;
659651 mutable Selector initWithObjectsS;
660652 mutable Selector initWithObjectsAndKeysS;
661- mutable std::unique_ptr<BugType> BT;
653+ const APIMisuse BT{this , " Arguments passed to variadic method aren't all "
654+ " Objective-C pointer types" };
662655
663656 bool isVariadicMessage (const ObjCMethodCall &msg) const ;
664657
@@ -717,11 +710,7 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
717710
718711void VariadicMethodTypeChecker::checkPreObjCMessage (const ObjCMethodCall &msg,
719712 CheckerContext &C) const {
720- if (!BT) {
721- BT.reset (new APIMisuse (this ,
722- " Arguments passed to variadic method aren't all "
723- " Objective-C pointer types" ));
724-
713+ if (arrayWithObjectsS.isNull ()) {
725714 ASTContext &Ctx = C.getASTContext ();
726715 arrayWithObjectsS = GetUnarySelector (" arrayWithObjects" , Ctx);
727716 dictionaryWithObjectsAndKeysS =
@@ -792,8 +781,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
792781 ArgTy.print (os, C.getLangOpts ());
793782 os << " '" ;
794783
795- auto R =
796- std::make_unique<PathSensitiveBugReport>(*BT, os.str (), *errorNode);
784+ auto R = std::make_unique<PathSensitiveBugReport>(BT, os.str (), *errorNode);
797785 R->addRange (msg.getArgSourceRange (I));
798786 C.emitReport (std::move (R));
799787 }
0 commit comments