[cfe-commits] r49455 - /cfe/trunk/lib/Analysis/CFRefCount.cpp

Ted Kremenek kremenek at apple.com
Wed Apr 9 16:49:12 PDT 2008


Author: kremenek
Date: Wed Apr  9 18:49:11 2008
New Revision: 49455

URL: http://llvm.org/viewvc/llvm-project?rev=49455&view=rev
Log:
Hooked up initial reference-count checks to the BugReporter interface.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=49455&r1=49454&r2=49455&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed Apr  9 18:49:11 2008
@@ -26,6 +26,10 @@
 
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+// Symbolic Evaluation of Reference Counting Logic
+//===----------------------------------------------------------------------===//
+
 namespace {  
   enum ArgEffect { IncRef, DecRef, DoNothing };
   typedef std::vector<ArgEffect> ArgEffects;
@@ -383,12 +387,62 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Bug Descriptions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  
+  class CFRefCount;
+  
+  class VISIBILITY_HIDDEN CFRefBug : public BugType {
+  protected:
+    CFRefCount& TF;
+    
+  public:
+    CFRefBug(CFRefCount& tf) : TF(tf) {}
+  };
+  
+  class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug {
+  public:
+    UseAfterRelease(CFRefCount& tf) : CFRefBug(tf) {}
+    
+    virtual const char* getName() const {
+      return "(CoreFoundation) use-after-release";
+    }
+    virtual const char* getDescription() const {
+      return "(CoreFoundation) Reference-counted object is used"
+      " after it is released.";
+    }
+    
+    virtual void EmitWarnings(BugReporter& BR);
+    
+  };
+  
+  class VISIBILITY_HIDDEN BadRelease : public CFRefBug {
+  public:
+    BadRelease(CFRefCount& tf) : CFRefBug(tf) {}
+    
+    virtual const char* getName() const {
+      return "(CoreFoundation) release of non-owned object";
+    }
+    virtual const char* getDescription() const {
+      return "Incorrect decrement of the reference count of a "
+      "CoreFoundation object:\n"
+      "The object is not owned at this point by the caller.";
+    }
+    
+    virtual void EmitWarnings(BugReporter& BR);
+  };
+  
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
 // Transfer functions.
 //===----------------------------------------------------------------------===//
 
 namespace {
   
-class RefVal {
+class VISIBILITY_HIDDEN RefVal {
   unsigned Data;
   
   RefVal(unsigned K, unsigned D) : Data((D << 3) | K) {
@@ -455,7 +509,7 @@
   }
 }
   
-class CFRefCount : public GRSimpleVals {
+class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
   
   // Type definitions.
   
@@ -502,6 +556,8 @@
 public:
   CFRefCount() {}
   virtual ~CFRefCount() {}
+  
+  virtual void RegisterChecks(GRExprEngine& Eng);
  
   virtual ValueState::CheckerStatePrinter* getCheckerStatePrinter() {
     return &Printer;
@@ -520,15 +576,22 @@
   typedef UseAfterReleasesTy::iterator use_after_iterator;  
   typedef ReleasesNotOwnedTy::iterator bad_release_iterator;
   
-  use_after_iterator begin_use_after() { return UseAfterReleases.begin(); }
-  use_after_iterator end_use_after() { return UseAfterReleases.end(); }
+  use_after_iterator use_after_begin() { return UseAfterReleases.begin(); }
+  use_after_iterator use_after_end() { return UseAfterReleases.end(); }
   
-  bad_release_iterator begin_bad_release() { return ReleasesNotOwned.begin(); }
-  bad_release_iterator end_bad_release() { return ReleasesNotOwned.end(); }
+  bad_release_iterator bad_release_begin() { return ReleasesNotOwned.begin(); }
+  bad_release_iterator bad_release_end() { return ReleasesNotOwned.end(); }
 };
 
 } // end anonymous namespace
 
+void CFRefCount::RegisterChecks(GRExprEngine& Eng) {
+  GRSimpleVals::RegisterChecks(Eng);
+  Eng.Register(new UseAfterRelease(*this));
+  Eng.Register(new BadRelease(*this));
+}
+
+
 void CFRefCount::BindingsPrinter::PrintCheckerState(std::ostream& Out,
                                                     void* State, const char* nl,
                                                     const char* sep) {
@@ -787,36 +850,28 @@
 
 
 //===----------------------------------------------------------------------===//
-// Bug Descriptions.
+// Error reporting.
 //===----------------------------------------------------------------------===//
 
-namespace {
-  
-class VISIBILITY_HIDDEN UseAfterRelease : public BugType {
+void UseAfterRelease::EmitWarnings(BugReporter& BR) {
 
-public:
-  virtual const char* getName() const {
-    return "(CoreFoundation) use-after-release";
-  }
-  virtual const char* getDescription() const {
-    return "(CoreFoundation) Reference-counted object is used"
-           " after it is released.";
-  }
-};
-  
-class VISIBILITY_HIDDEN BadRelease : public BugType {
-  
-public:
-  virtual const char* getName() const {
-    return "(CoreFoundation) release of non-owned object";
-  }
-  virtual const char* getDescription() const {
-    return "Incorrect decrement of reference count of CoreFoundation object:\n"
-           "The object is not owned at this point by the caller.";
+  for (CFRefCount::use_after_iterator I = TF.use_after_begin(),
+        E = TF.use_after_end(); I != E; ++I) {
+    
+    BugReport report(*this);
+    BR.EmitPathWarning(report, *I);    
   }
-};
+}
+
+void BadRelease::EmitWarnings(BugReporter& BR) {
   
-} // end anonymous namespace
+  for (CFRefCount::bad_release_iterator I = TF.bad_release_begin(),
+       E = TF.bad_release_end(); I != E; ++I) {
+    
+    BugReport report(*this);
+    BR.EmitPathWarning(report, *I);    
+  }  
+}
 
 //===----------------------------------------------------------------------===//
 // Driver for the CFRefCount Checker.





More information about the cfe-commits mailing list