]> granicus.if.org Git - clang/commitdiff
Generalize caching mechanism for bugs reports. Now individual BugTypes
authorTed Kremenek <kremenek@apple.com>
Fri, 18 Apr 2008 20:54:29 +0000 (20:54 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 18 Apr 2008 20:54:29 +0000 (20:54 +0000)
can decide the policy on how to cache related bugs.  This allows us to
properly to handle warning about multiple leaks in the same location in the
ref count checker (not yet done).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49918 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/BugReporter.h
lib/Analysis/BasicObjCFoundationChecks.cpp
lib/Analysis/BugReporter.cpp
lib/Analysis/CFRefCount.cpp
lib/Analysis/DeadStores.cpp
lib/Analysis/GRSimpleVals.cpp

index f2f2e0316610a11f29b14c041a6d5bd24d32ab93..325e1a750f19c82f4de317662c6613e2482fb6e5 100644 (file)
@@ -32,6 +32,7 @@ class BugReporter;
 class GRExprEngine;
 class ValueState;
 class Stmt;
+class BugReport;
   
 class BugType {
 public:
@@ -43,17 +44,29 @@ public:
       
   virtual void EmitWarnings(BugReporter& BR) {}
   virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {}
+  
+  virtual bool isCached(BugReport& R) = 0;
+};
+  
+class BugTypeCacheLocation : public BugType {
+  llvm::SmallPtrSet<void*,10> CachedErrors;
+public:
+  BugTypeCacheLocation() {}
+  virtual ~BugTypeCacheLocation() {}  
+  virtual bool isCached(BugReport& R);
 };
   
+  
 class BugReport {
-  const BugType& Desc;
+  BugType& Desc;
   ExplodedNode<ValueState> *N;
   
 public:
-  BugReport(const BugType& D, ExplodedNode<ValueState> *n) : Desc(D), N(n) {}
+  BugReport(BugType& D, ExplodedNode<ValueState> *n) : Desc(D), N(n) {}
   virtual ~BugReport();
   
   const BugType& getBugType() const { return Desc; }
+  BugType& getBugType() { return Desc; }
   
   ExplodedNode<ValueState>* getEndNode() const { return N; }
   
@@ -82,7 +95,7 @@ public:
 class RangedBugReport : public BugReport {
   std::vector<SourceRange> Ranges;
 public:
-  RangedBugReport(const BugType& D, ExplodedNode<ValueState> *n)
+  RangedBugReport(BugType& D, ExplodedNode<ValueState> *n)
     : BugReport(D, n) {}
   
   virtual ~RangedBugReport();
@@ -104,7 +117,6 @@ public:
 };
   
 class BugReporter {
-  llvm::SmallPtrSet<void*,10> CachedErrors;
   Diagnostic& Diag;
   PathDiagnosticClient* PD;
   ASTContext& Ctx;
@@ -130,10 +142,6 @@ public:
   CFG& getCFG() { return getGraph().getCFG(); }
   
   void EmitWarning(BugReport& R);
-    
-  void clearCache() { CachedErrors.clear(); }
-  
-  bool IsCached(ExplodedNode<ValueState>* N);
   
   void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
 };
index 958f85dff9a2bba66837813aca4f1e9aef2215eb..7e51aee17b7a9ae2d651723056eaaceeeaa5355a 100644 (file)
@@ -54,7 +54,7 @@ static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
 
 namespace {
   
-class VISIBILITY_HIDDEN NilArg : public BugType {
+class VISIBILITY_HIDDEN NilArg : public BugTypeCacheLocation {
 public:
   virtual ~NilArg() {}
   
index e74295c31133526917862b140ed76658696e053d..e69c5a6d3ffa816ef4196122e6b71febc4d4a6be 100644 (file)
@@ -357,12 +357,14 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
   }
 }
 
-bool BugReporter::IsCached(ExplodedNode<ValueState>* N) {
+bool BugTypeCacheLocation::isCached(BugReport& R) {
+  
+  ExplodedNode<ValueState>* N = R.getEndNode();
   
   if (!N)
     return false;
-  
-  // HACK: Cache the location of the error.  Don't emit the same
+
+  // Cache the location of the error.  Don't emit the same
   // warning for the same error type that occurs at the same program
   // location but along a different path.
   
@@ -371,14 +373,13 @@ bool BugReporter::IsCached(ExplodedNode<ValueState>* N) {
   if (CachedErrors.count(p))
     return true;
   
-  CachedErrors.insert(p);
-  
+  CachedErrors.insert(p);  
   return false;
 }
 
 void BugReporter::EmitWarning(BugReport& R) {
 
-  if (IsCached(R.getEndNode()))
+  if (R.getBugType().isCached(R))
     return;
 
   PathDiagnostic D(R.getName());  
index 3eb037978a1d29375fa27159ece81eb8e9aef138..253e00589e04a8557075f8e3939286f37fd9ed65 100644 (file)
@@ -1268,7 +1268,7 @@ namespace {
   // Bug Descriptions. //
   //===-------------===//  
   
-  class VISIBILITY_HIDDEN CFRefBug : public BugType {
+  class VISIBILITY_HIDDEN CFRefBug : public BugTypeCacheLocation {
   protected:
     CFRefCount& TF;
     
@@ -1331,7 +1331,7 @@ namespace {
   class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
     SymbolID Sym;
   public:
-    CFRefReport(const BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
+    CFRefReport(BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
       : RangedBugReport(D, n), Sym(sym) {}
         
     virtual ~CFRefReport() {}
index 719b5eb6c0dd83c0abbdb6f5e59ab4f8b9b4f104..6858e3ab370c40d3edd9d8730a72908899eeb9cf 100644 (file)
@@ -109,7 +109,7 @@ class VISIBILITY_HIDDEN DiagBugReport : public RangedBugReport {
   std::list<std::string> Strs;
   FullSourceLoc L;
 public:
-  DiagBugReport(const BugType& D, FullSourceLoc l) :
+  DiagBugReport(BugType& D, FullSourceLoc l) :
     RangedBugReport(D, NULL), L(l) {}
   
   virtual ~DiagBugReport() {}
@@ -124,7 +124,7 @@ public:
   
 class VISIBILITY_HIDDEN DiagCollector : public DiagnosticClient {
   std::list<DiagBugReport> Reports;
-  const BugType& D;
+  BugType& D;
 public:
   DiagCollector(BugType& d) : D(d) {}
   
@@ -159,7 +159,7 @@ public:
   iterator end() { return Reports.end(); }
 };
   
-class VISIBILITY_HIDDEN DeadStoresChecker : public BugType {
+class VISIBILITY_HIDDEN DeadStoresChecker : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "dead store";
index ea8762aa0c9d7b6c4c8263d658971e4c2b652fe5..2c14dde08bdaf7d68814e86b0cc50e777681dc16 100644 (file)
@@ -40,8 +40,7 @@ ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
 }
 
 template <typename ITER>
-void GenericEmitWarnings(BugReporter& BR, const BugType& D,
-                         ITER I, ITER E) {
+void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
   
   for (; I != E; ++I) {
     BugReport R(D, GetNode(I));    
@@ -55,7 +54,7 @@ void GenericEmitWarnings(BugReporter& BR, const BugType& D,
 
 namespace {
   
-class VISIBILITY_HIDDEN NullDeref : public BugType {
+class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "null dereference";
@@ -72,7 +71,7 @@ public:
   }
 };
 
-class VISIBILITY_HIDDEN UndefDeref : public BugType {
+class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "bad dereference";
@@ -89,7 +88,7 @@ public:
   }
 };
   
-class VISIBILITY_HIDDEN UndefBranch : public BugType {
+class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "uninitialized value";
@@ -106,7 +105,7 @@ public:
   }
 };
   
-class VISIBILITY_HIDDEN DivZero : public BugType {
+class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "divide-by-zero";
@@ -123,7 +122,7 @@ public:
   }
 };
 
-class VISIBILITY_HIDDEN UndefResult : public BugType {
+class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "undefined result";
@@ -140,7 +139,7 @@ public:
   }
 };
   
-class VISIBILITY_HIDDEN BadCall : public BugType {
+class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "invalid function call";
@@ -158,7 +157,7 @@ public:
 };
   
   
-class VISIBILITY_HIDDEN BadArg : public BugType {
+class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
 public:
   
   virtual ~BadArg() {}
@@ -214,7 +213,7 @@ public:
   }
 };
 
-class VISIBILITY_HIDDEN BadReceiver : public BugType {
+class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
 public:  
   virtual const char* getName() const {
     return "bad receiver";
@@ -245,7 +244,7 @@ public:
   }
 };
   
-class VISIBILITY_HIDDEN RetStack : public BugType {
+class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "return of stack address";