xazax.hun updated this revision to Diff 113837.
xazax.hun retitled this revision from "[analyzer] Fix SimpleStreamChecker's 
output plist not containing the checker name" to "[analyzer] Fix some checker's 
output plist not containing the checker name".
xazax.hun edited the summary of this revision.
xazax.hun added a comment.

- Fix more checkers
- Minor style fixes along the way
- Added an assert to prevent such errors in the future


https://reviews.llvm.org/D37437

Files:
  include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
  lib/StaticAnalyzer/Checkers/CStringChecker.cpp
  lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
  lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
  lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
  lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
  lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
  lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
  lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
  lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
  lib/StaticAnalyzer/Checkers/ValistChecker.cpp
  test/Analysis/malloc.c

Index: test/Analysis/malloc.c
===================================================================
--- test/Analysis/malloc.c
+++ test/Analysis/malloc.c
@@ -1720,13 +1720,6 @@
   }
 }
 
-char *dupstrWarn(const char *s) {
-  const int len = strlen(s);
-  char *p = (char*) smallocWarn(len + 1);
-  strcpy(p, s); // expected-warning{{String copy function overflows destination buffer}}
-  return p;
-}
-
 int *radar15580979() {
   int *data = (int *)malloc(32);
   int *p = data ?: (int*)malloc(32); // no warning
Index: lib/StaticAnalyzer/Checkers/ValistChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -64,7 +64,7 @@
                                  CheckerContext &C) const;
   void reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1,
                            StringRef Msg2, CheckerContext &C, ExplodedNode *N,
-                           bool ForceReport = false) const;
+                           bool ReportUninit = false) const;
 
   void checkVAListStartCall(const CallEvent &Call, CheckerContext &C,
                             bool IsCopy) const;
@@ -267,15 +267,15 @@
 void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
                                         StringRef Msg1, StringRef Msg2,
                                         CheckerContext &C, ExplodedNode *N,
-                                        bool ForceReport) const {
+                                        bool ReportUninit) const {
   if (!(ChecksEnabled[CK_Unterminated] ||
-        (ChecksEnabled[CK_Uninitialized] && ForceReport)))
+        (ChecksEnabled[CK_Uninitialized] && ReportUninit)))
     return;
   for (auto Reg : LeakedVALists) {
     if (!BT_leakedvalist) {
-      BT_leakedvalist.reset(new BugType(CheckNames[CK_Unterminated],
-                                        "Leaked va_list",
-                                        categories::MemoryError));
+      BT_leakedvalist.reset(new BugType(
+          CheckNames[ReportUninit ? CK_Uninitialized : CK_Unterminated],
+          "Leaked va_list", categories::MemoryError));
       BT_leakedvalist->setSuppressOnSink(true);
     }
 
@@ -375,7 +375,7 @@
 
 std::shared_ptr<PathDiagnosticPiece> ValistChecker::ValistBugVisitor::VisitNode(
     const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-    BugReport &BR) {
+    BugReport &) {
   ProgramStateRef State = N->getState();
   ProgramStateRef StatePrev = PrevN->getState();
 
Index: lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -54,8 +54,8 @@
                                            check::PointerEscape> {
   CallDescription OpenFn, CloseFn;
 
-  std::unique_ptr<BugType> DoubleCloseBugType;
-  std::unique_ptr<BugType> LeakBugType;
+  mutable std::unique_ptr<BugType> DoubleCloseBugType;
+  mutable std::unique_ptr<BugType> LeakBugType;
 
   void reportDoubleClose(SymbolRef FileDescSym,
                          const CallEvent &Call,
@@ -104,16 +104,7 @@
 } // end anonymous namespace
 
 SimpleStreamChecker::SimpleStreamChecker()
-    : OpenFn("fopen"), CloseFn("fclose", 1) {
-  // Initialize the bug types.
-  DoubleCloseBugType.reset(
-      new BugType(this, "Double fclose", "Unix Stream API Error"));
-
-  LeakBugType.reset(
-      new BugType(this, "Resource Leak", "Unix Stream API Error"));
-  // Sinks are higher importance bugs as well as calls to assert() or exit(0).
-  LeakBugType->setSuppressOnSink(true);
-}
+    : OpenFn("fopen"), CloseFn("fclose", 1) {}
 
 void SimpleStreamChecker::checkPostCall(const CallEvent &Call,
                                         CheckerContext &C) const {
@@ -206,6 +197,10 @@
   if (!ErrNode)
     return;
 
+  if (!DoubleCloseBugType)
+    DoubleCloseBugType.reset(
+        new BugType(this, "Double fclose", "Unix Stream API Error"));
+
   // Generate the report.
   auto R = llvm::make_unique<BugReport>(*DoubleCloseBugType,
       "Closing a previously closed file stream", ErrNode);
@@ -217,6 +212,13 @@
 void SimpleStreamChecker::reportLeaks(ArrayRef<SymbolRef> LeakedStreams,
                                       CheckerContext &C,
                                       ExplodedNode *ErrNode) const {
+
+  if (!LeakBugType) {
+    LeakBugType.reset(
+        new BugType(this, "Resource Leak", "Unix Stream API Error"));
+    // Sinks are higher importance bugs as well as calls to assert() or exit(0).
+    LeakBugType->setSuppressOnSink(true);
+  }
   // Attach bug reports to the leak node.
   // TODO: Identify the leaked file descriptor.
   for (SymbolRef LeakedStream : LeakedStreams) {
Index: lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
@@ -31,7 +31,7 @@
   mutable IdentifierInfo *IIdealloc, *IINSObject;
   mutable Selector SELdealloc;
 
-  std::unique_ptr<BugType> DoubleSuperDeallocBugType;
+  mutable std::unique_ptr<BugType> DoubleSuperDeallocBugType;
 
   void initIdentifierInfoAndSelectors(ASTContext &Ctx) const;
 
@@ -193,6 +193,11 @@
   if (Desc.empty())
     Desc = "Use of 'self' after it has been deallocated";
 
+  if (!DoubleSuperDeallocBugType)
+    DoubleSuperDeallocBugType.reset(
+        new BugType(this, "[super dealloc] should not be called more than once",
+                    categories::CoreFoundationObjectiveC));
+
   // Generate the report.
   std::unique_ptr<BugReport> BR(
       new BugReport(*DoubleSuperDeallocBugType, Desc, ErrNode));
@@ -220,12 +225,7 @@
 }
 
 ObjCSuperDeallocChecker::ObjCSuperDeallocChecker()
-    : IIdealloc(nullptr), IINSObject(nullptr) {
-
-  DoubleSuperDeallocBugType.reset(
-      new BugType(this, "[super dealloc] should not be called more than once",
-                  categories::CoreFoundationObjectiveC));
-}
+    : IIdealloc(nullptr), IINSObject(nullptr) {}
 
 void
 ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const {
@@ -252,7 +252,7 @@
 std::shared_ptr<PathDiagnosticPiece>
 SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
                                  const ExplodedNode *Pred,
-                                 BugReporterContext &BRC, BugReport &BR) {
+                                 BugReporterContext &BRC, BugReport &) {
   if (Satisfied)
     return nullptr;
 
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -2900,8 +2900,13 @@
       mgr.getCurrentCheckName();
   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
   // checker.
-  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
+  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
     checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
+    // FIXME: This does not set the correct name, but without this workaround
+    //        no name will be set at all.
+    checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
+        mgr.getCurrentCheckName();
+  }
 }
 
 #define REGISTER_CHECKER(name)                                                 \
Index: lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
===================================================================
--- lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
+++ lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
@@ -30,9 +30,7 @@
 
 class MPIChecker : public Checker<check::PreCall, check::DeadSymbols> {
 public:
-  MPIChecker() : BReporter(*this) {}
-
-  // path-sensitive callbacks
+  // Path-sensitive callbacks.
   void checkPreCall(const CallEvent &CE, CheckerContext &Ctx) const {
     dynamicInit(Ctx);
     checkUnmatchedWaits(CE, Ctx);
Index: lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
@@ -44,7 +44,7 @@
   if (Req && Req->CurrentState == Request::State::Nonblocking) {
     ExplodedNode *ErrorNode = Ctx.generateNonFatalErrorNode();
     BReporter.reportDoubleNonblocking(PreCallEvent, *Req, MR, ErrorNode,
-                                      Ctx.getBugReporter());
+                                      Ctx.getBugReporter(), *this);
     Ctx.addTransition(ErrorNode->getState(), ErrorNode);
   }
   // no error
@@ -87,7 +87,7 @@
       }
       // A wait has no matching nonblocking call.
       BReporter.reportUnmatchedWait(PreCallEvent, ReqRegion, ErrorNode,
-                                    Ctx.getBugReporter());
+                                    Ctx.getBugReporter(), *this);
     }
   }
 
@@ -121,7 +121,7 @@
           State = ErrorNode->getState();
         }
         BReporter.reportMissingWait(Req.second, Req.first, ErrorNode,
-                                    Ctx.getBugReporter());
+                                    Ctx.getBugReporter(), *this);
       }
       State = State->remove<RequestMap>(Req.first);
     }
Index: lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
===================================================================
--- lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
+++ lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
@@ -25,13 +25,6 @@
 
 class MPIBugReporter {
 public:
-  MPIBugReporter(const CheckerBase &CB) {
-    UnmatchedWaitBugType.reset(new BugType(&CB, "Unmatched wait", MPIError));
-    DoubleNonblockingBugType.reset(
-        new BugType(&CB, "Double nonblocking", MPIError));
-    MissingWaitBugType.reset(new BugType(&CB, "Missing wait", MPIError));
-  }
-
   /// Report duplicate request use by nonblocking calls without intermediate
   /// wait.
   ///
@@ -44,7 +37,8 @@
                                const Request &Req,
                                const MemRegion *const RequestRegion,
                                const ExplodedNode *const ExplNode,
-                              BugReporter &BReporter) const;
+                               BugReporter &BReporter,
+                               const CheckerBase &CB) const;
 
   /// Report a missing wait for a nonblocking call.
   ///
@@ -55,7 +49,7 @@
   void reportMissingWait(const Request &Req,
                          const MemRegion *const RequestRegion,
                          const ExplodedNode *const ExplNode,
-                         BugReporter &BReporter) const;
+                         BugReporter &BReporter, const CheckerBase &CB) const;
 
   /// Report a wait on a request that has not been used at all before.
   ///
@@ -66,15 +60,15 @@
   void reportUnmatchedWait(const CallEvent &CE,
                            const MemRegion *const RequestRegion,
                            const ExplodedNode *const ExplNode,
-                           BugReporter &BReporter) const;
+                           BugReporter &BReporter, const CheckerBase &CB) const;
 
 private:
   const std::string MPIError = "MPI Error";
 
-  // path-sensitive bug types
-  std::unique_ptr<BugType> UnmatchedWaitBugType;
-  std::unique_ptr<BugType> MissingWaitBugType;
-  std::unique_ptr<BugType> DoubleNonblockingBugType;
+  // Path-sensitive bug types.
+  mutable std::unique_ptr<BugType> UnmatchedWaitBugType;
+  mutable std::unique_ptr<BugType> MissingWaitBugType;
+  mutable std::unique_ptr<BugType> DoubleNonblockingBugType;
 
   /// Bug visitor class to find the node where the request region was previously
   /// used in order to include it into the BugReport path.
Index: lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
+++ lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
@@ -23,9 +23,11 @@
 
 void MPIBugReporter::reportDoubleNonblocking(
     const CallEvent &MPICallEvent, const ento::mpi::Request &Req,
-    const MemRegion *const RequestRegion,
-    const ExplodedNode *const ExplNode,
-    BugReporter &BReporter) const {
+    const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode,
+    BugReporter &BReporter, const CheckerBase &CB) const {
+  if (!DoubleNonblockingBugType)
+    DoubleNonblockingBugType.reset(
+        new BugType(&CB, "Double nonblocking", MPIError));
 
   std::string ErrorText;
   ErrorText = "Double nonblocking on request " +
@@ -47,10 +49,14 @@
   BReporter.emitReport(std::move(Report));
 }
 
-void MPIBugReporter::reportMissingWait(
-    const ento::mpi::Request &Req, const MemRegion *const RequestRegion,
-    const ExplodedNode *const ExplNode,
-    BugReporter &BReporter) const {
+void MPIBugReporter::reportMissingWait(const ento::mpi::Request &Req,
+                                       const MemRegion *const RequestRegion,
+                                       const ExplodedNode *const ExplNode,
+                                       BugReporter &BReporter,
+                                       const CheckerBase &CB) const {
+  if (!MissingWaitBugType)
+    MissingWaitBugType.reset(new BugType(&CB, "Missing wait", MPIError));
+
   std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
                         " has no matching wait. "};
 
@@ -69,8 +75,11 @@
 
 void MPIBugReporter::reportUnmatchedWait(
     const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion,
-    const ExplodedNode *const ExplNode,
-    BugReporter &BReporter) const {
+    const ExplodedNode *const ExplNode, BugReporter &BReporter,
+    const CheckerBase &CB) const {
+  if (!UnmatchedWaitBugType)
+    UnmatchedWaitBugType.reset(new BugType(&CB, "Unmatched wait", MPIError));
+
   std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
                         " has no matching nonblocking call. "};
 
Index: lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -88,8 +88,6 @@
                                       Selector S) const;
 
 public:
-  NonLocalizedStringChecker();
-
   // When this parameter is set to true, the checker assumes all
   // methods that return NSStrings are unlocalized. Thus, more false
   // positives will be reported.
@@ -107,11 +105,6 @@
 REGISTER_MAP_WITH_PROGRAMSTATE(LocalizedMemMap, const MemRegion *,
                                LocalizedState)
 
-NonLocalizedStringChecker::NonLocalizedStringChecker() {
-  BT.reset(new BugType(this, "Unlocalizable string",
-                       "Localizability Issue (Apple)"));
-}
-
 namespace {
 class NonLocalizedStringBRVisitor final
     : public BugReporterVisitorImpl<NonLocalizedStringBRVisitor> {
@@ -764,6 +757,10 @@
   if (!ErrNode)
     return;
 
+  if (!BT)
+    BT.reset(new BugType(this, "Unlocalizable string",
+                         "Localizability Issue (Apple)"));
+
   // Generate the bug report.
   std::unique_ptr<BugReport> R(new BugReport(
       *BT, "User-facing text should use localized string macro", ErrNode));
Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
+++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
@@ -171,7 +171,7 @@
                      check::DeadSymbols,
                      eval::Assume> {
 
-  std::unique_ptr<BugType> OutOfRangeBugType;
+  mutable std::unique_ptr<BugType> OutOfRangeBugType;
 
   void handleComparison(CheckerContext &C, const SVal &RetVal, const SVal &LVal,
                         const SVal &RVal, OverloadedOperatorKind Op) const;
@@ -184,8 +184,6 @@
                            CheckerContext &C, ExplodedNode *ErrNode) const;
 
 public:
-  IteratorChecker();
-
   enum CheckKind {
     CK_IteratorRangeChecker,
     CK_NumCheckKinds
@@ -257,12 +255,6 @@
 bool isOutOfRange(ProgramStateRef State, const IteratorPosition &Pos);
 } // namespace
 
-IteratorChecker::IteratorChecker() {
-  OutOfRangeBugType.reset(
-      new BugType(this, "Iterator out of range", "Misuse of STL APIs"));
-  OutOfRangeBugType->setSuppressOnSink(true);
-}
-
 void IteratorChecker::checkPreCall(const CallEvent &Call,
                                    CheckerContext &C) const {
   // Check for out of range access
@@ -522,6 +514,12 @@
 void IteratorChecker::reportOutOfRangeBug(const StringRef &Message,
                                           const SVal &Val, CheckerContext &C,
                                           ExplodedNode *ErrNode) const {
+
+  if (!OutOfRangeBugType) {
+    OutOfRangeBugType.reset(
+        new BugType(this, "Iterator out of range", "Misuse of STL APIs"));
+    OutOfRangeBugType->setSuppressOnSink(true);
+  }
   auto R = llvm::make_unique<BugReport>(*OutOfRangeBugType, Message, ErrNode);
   R->markInteresting(Val);
   C.emitReport(std::move(R));
Index: lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -104,9 +104,9 @@
 
   mutable Selector DeallocSel, ReleaseSel;
 
-  std::unique_ptr<BugType> MissingReleaseBugType;
-  std::unique_ptr<BugType> ExtraReleaseBugType;
-  std::unique_ptr<BugType> MistakenDeallocBugType;
+  mutable std::unique_ptr<BugType> MissingReleaseBugType;
+  mutable std::unique_ptr<BugType> ExtraReleaseBugType;
+  mutable std::unique_ptr<BugType> MistakenDeallocBugType;
 
 public:
   ObjCDeallocChecker();
@@ -585,6 +585,11 @@
     OS << " by a synthesized property but not released"
           " before '[super dealloc]'";
 
+    if (!MissingReleaseBugType)
+      MissingReleaseBugType.reset(
+          new BugType(this, "Missing ivar release (leak)",
+                      categories::MemoryCoreFoundationObjectiveC));
+
     std::unique_ptr<BugReport> BR(
         new BugReport(*MissingReleaseBugType, OS.str(), ErrNode));
 
@@ -708,6 +713,11 @@
     OS <<  " property but was released in 'dealloc'";
   }
 
+  if (!ExtraReleaseBugType)
+    ExtraReleaseBugType.reset(
+        new BugType(this, "Extra ivar release",
+                    categories::MemoryCoreFoundationObjectiveC));
+
   std::unique_ptr<BugReport> BR(
       new BugReport(*ExtraReleaseBugType, OS.str(), ErrNode));
   BR->addRange(M.getOriginExpr()->getSourceRange());
@@ -746,6 +756,10 @@
   OS << "'" << *PropImpl->getPropertyIvarDecl()
      << "' should be released rather than deallocated";
 
+  if (!MistakenDeallocBugType)
+    MistakenDeallocBugType.reset(new BugType(
+        this, "Mistaken dealloc", categories::MemoryCoreFoundationObjectiveC));
+
   std::unique_ptr<BugReport> BR(
       new BugReport(*MistakenDeallocBugType, OS.str(), ErrNode));
   BR->addRange(M.getOriginExpr()->getSourceRange());
@@ -757,20 +771,7 @@
 
 ObjCDeallocChecker::ObjCDeallocChecker()
     : NSObjectII(nullptr), SenTestCaseII(nullptr), XCTestCaseII(nullptr),
-      CIFilterII(nullptr) {
-
-  MissingReleaseBugType.reset(
-      new BugType(this, "Missing ivar release (leak)",
-                  categories::MemoryCoreFoundationObjectiveC));
-
-  ExtraReleaseBugType.reset(
-      new BugType(this, "Extra ivar release",
-                  categories::MemoryCoreFoundationObjectiveC));
-
-  MistakenDeallocBugType.reset(
-      new BugType(this, "Mistaken dealloc",
-                  categories::MemoryCoreFoundationObjectiveC));
-}
+      CIFilterII(nullptr) {}
 
 void ObjCDeallocChecker::initIdentifierInfoAndSelectors(
     ASTContext &Ctx) const {
Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -305,6 +305,9 @@
   ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
   ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
   if (StOutBound && !StInBound) {
+    if (!Filter.CheckCStringOutOfBounds)
+      return state;
+
     ExplodedNode *N = C.generateErrorNode(StOutBound);
     if (!N)
       return nullptr;
Index: lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -26,14 +26,13 @@
 
 namespace {
 
-class BlockInCriticalSectionChecker : public Checker<check::PostCall,
-                                                     check::PreCall> {
+class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
 
   CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn,
                   PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn,
                   MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock;
 
-  std::unique_ptr<BugType> BlockInCritSectionBugType;
+  mutable std::unique_ptr<BugType> BlockInCritSectionBugType;
 
   void reportBlockInCritSection(SymbolRef FileDescSym,
                                 const CallEvent &call,
@@ -46,8 +45,6 @@
   bool isLockFunction(const CallEvent &Call) const;
   bool isUnlockFunction(const CallEvent &Call) const;
 
-  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
-
   /// Process unlock.
   /// Process lock.
   /// Process blocking functions (sleep, getc, fgets, read, recv)
@@ -64,16 +61,9 @@
       FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
       PthreadLockFn("pthread_mutex_lock"),
       PthreadTryLockFn("pthread_mutex_trylock"),
-      PthreadUnlockFn("pthread_mutex_unlock"),
-      MtxLock("mtx_lock"),
-      MtxTimedLock("mtx_timedlock"),
-      MtxTryLock("mtx_trylock"),
-      MtxUnlock("mtx_unlock") {
-  // Initialize the bug type.
-  BlockInCritSectionBugType.reset(
-      new BugType(this, "Call to blocking function in critical section",
-                        "Blocking Error"));
-}
+      PthreadUnlockFn("pthread_mutex_unlock"), MtxLock("mtx_lock"),
+      MtxTimedLock("mtx_timedlock"), MtxTryLock("mtx_trylock"),
+      MtxUnlock("mtx_unlock") {}
 
 bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
   if (Call.isCalled(SleepFn)
@@ -107,10 +97,6 @@
   return false;
 }
 
-void BlockInCriticalSectionChecker::checkPreCall(const CallEvent &Call,
-                                                 CheckerContext &C) const {
-}
-
 void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
                                                   CheckerContext &C) const {
   if (!isBlockingFunction(Call)
@@ -142,7 +128,12 @@
   llvm::raw_string_ostream os(msg);
   os << "Call to blocking function '" << Call.getCalleeIdentifier()->getName()
      << "' inside of critical section";
-  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType, os.str(), ErrNode);
+  if (!BlockInCritSectionBugType)
+    BlockInCritSectionBugType.reset(
+        new BugType(this, "Call to blocking function in critical section",
+                    "Blocking Error"));
+  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType, os.str(),
+                                        ErrNode);
   R->addRange(Call.getSourceRange());
   R->markInteresting(BlockDescSym);
   C.emitReport(std::move(R));
Index: include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
===================================================================
--- include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -32,15 +32,19 @@
   const CheckName Check;
   const std::string Name;
   const std::string Category;
-  bool SuppressonSink;
+  bool SuppressOnSink;
 
   virtual void anchor();
 public:
-  BugType(class CheckName check, StringRef name, StringRef cat)
-      : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
-  BugType(const CheckerBase *checker, StringRef name, StringRef cat)
-      : Check(checker->getCheckName()), Name(name), Category(cat),
-        SuppressonSink(false) {}
+  BugType(class CheckName Check, StringRef Name, StringRef Cat)
+      : Check(Check), Name(Name), Category(Cat), SuppressOnSink(false) {
+    assert(!getCheckName().empty() && "Check name is not set properly.");
+  }
+  BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat)
+      : Check(Checker->getCheckName()), Name(Name), Category(Cat),
+        SuppressOnSink(false) {
+    assert(!getCheckName().empty() && "Check name is not set properly.");
+  }
   virtual ~BugType() {}
 
   // FIXME: Should these be made strings as well?
@@ -51,8 +55,8 @@
   /// isSuppressOnSink - Returns true if bug reports associated with this bug
   ///  type should be suppressed if the end node of the report is post-dominated
   ///  by a sink node.
-  bool isSuppressOnSink() const { return SuppressonSink; }
-  void setSuppressOnSink(bool x) { SuppressonSink = x; }
+  bool isSuppressOnSink() const { return SuppressOnSink; }
+  void setSuppressOnSink(bool x) { SuppressOnSink = x; }
 
   virtual void FlushReports(BugReporter& BR);
 };
@@ -74,7 +78,7 @@
   StringRef getDescription() const { return desc; }
 };
 
-} // end GR namespace
+} // end ento namespace
 
 } // end clang namespace
 #endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to