[cfe-commits] r138419 - /cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp

Eric Christopher echristo at apple.com
Tue Aug 23 17:39:49 PDT 2011


Author: echristo
Date: Tue Aug 23 19:39:48 2011
New Revision: 138419

URL: http://llvm.org/viewvc/llvm-project?rev=138419&view=rev
Log:
Revert "[analyzer] Make CFRefBug and CFRefReportVisitor not dependent on CFRefCount. Unfortunately, CFRefReport still is. No functionality change."

This reverts commit e3fb7e428b7ba0d5d902dfe3f165d70e09b03a15.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=138419&r1=138418&r2=138419&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Tue Aug 23 19:39:48 2011
@@ -1742,6 +1742,8 @@
 //===----------------------------------------------------------------------===//
 // Error reporting.
 //===----------------------------------------------------------------------===//
+static void addExtraTextToCFReport(BugReport &R);
+
 namespace {
   typedef llvm::DenseMap<const ExplodedNode *, const RetainSummary *>
     SummaryLogTy;
@@ -1752,30 +1754,35 @@
 
   class CFRefBug : public BugType {
   protected:
-    CFRefBug(StringRef name)
-    : BugType(name, "Memory (Core Foundation/Objective-C)") {}
+    CFRefCount& TF;
+
+    CFRefBug(CFRefCount* tf, StringRef name)
+    : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}
   public:
 
+    CFRefCount& getTF() { return TF; }
+
     // FIXME: Eventually remove.
-    virtual const char *getDescription() const = 0;
+    virtual const char* getDescription() const = 0;
 
     virtual bool isLeak() const { return false; }
   };
 
   class UseAfterRelease : public CFRefBug {
   public:
-    UseAfterRelease() : CFRefBug("Use-after-release") {}
+    UseAfterRelease(CFRefCount* tf)
+    : CFRefBug(tf, "Use-after-release") {}
 
-    const char *getDescription() const {
+    const char* getDescription() const {
       return "Reference-counted object is used after it is released";
     }
   };
 
   class BadRelease : public CFRefBug {
   public:
-    BadRelease() : CFRefBug("Bad release") {}
+    BadRelease(CFRefCount* tf) : CFRefBug(tf, "Bad release") {}
 
-    const char *getDescription() const {
+    const char* getDescription() const {
       return "Incorrect decrement of the reference count of an object that is "
              "not owned at this point by the caller";
     }
@@ -1783,8 +1790,8 @@
 
   class DeallocGC : public CFRefBug {
   public:
-    DeallocGC()
-    : CFRefBug("-dealloc called while using garbage collection") {}
+    DeallocGC(CFRefCount *tf)
+      : CFRefBug(tf, "-dealloc called while using garbage collection") {}
 
     const char *getDescription() const {
       return "-dealloc called while using garbage collection";
@@ -1793,8 +1800,8 @@
 
   class DeallocNotOwned : public CFRefBug {
   public:
-    DeallocNotOwned()
-    : CFRefBug("-dealloc sent to non-exclusively owned object") {}
+    DeallocNotOwned(CFRefCount *tf)
+      : CFRefBug(tf, "-dealloc sent to non-exclusively owned object") {}
 
     const char *getDescription() const {
       return "-dealloc sent to object that may be referenced elsewhere";
@@ -1803,8 +1810,8 @@
 
   class OverAutorelease : public CFRefBug {
   public:
-    OverAutorelease()
-    : CFRefBug("Object sent -autorelease too many times") {}
+    OverAutorelease(CFRefCount *tf) :
+      CFRefBug(tf, "Object sent -autorelease too many times") {}
 
     const char *getDescription() const {
       return "Object sent -autorelease too many times";
@@ -1813,8 +1820,8 @@
 
   class ReturnedNotOwnedForOwned : public CFRefBug {
   public:
-    ReturnedNotOwnedForOwned()
-    : CFRefBug("Method should return an owned object") {}
+    ReturnedNotOwnedForOwned(CFRefCount *tf) :
+      CFRefBug(tf, "Method should return an owned object") {}
 
     const char *getDescription() const {
       return "Object with a +0 retain count returned to caller where a +1 "
@@ -1825,25 +1832,25 @@
   class Leak : public CFRefBug {
     const bool isReturn;
   protected:
-    Leak(StringRef name, bool isRet)
-    : CFRefBug(name), isReturn(isRet) {}
+    Leak(CFRefCount* tf, StringRef name, bool isRet)
+    : CFRefBug(tf, name), isReturn(isRet) {}
   public:
 
-    const char *getDescription() const { return ""; }
+    const char* getDescription() const { return ""; }
 
     bool isLeak() const { return true; }
   };
 
   class LeakAtReturn : public Leak {
   public:
-    LeakAtReturn(StringRef name)
-    : Leak(name, true) {}
+    LeakAtReturn(CFRefCount* tf, StringRef name)
+    : Leak(tf, name, true) {}
   };
 
   class LeakWithinFunction : public Leak {
   public:
-    LeakWithinFunction(StringRef name)
-    : Leak(name, false) {}
+    LeakWithinFunction(CFRefCount* tf, StringRef name)
+    : Leak(tf, name, false) {}
   };
 
   //===---------===//
@@ -1853,12 +1860,13 @@
   class CFRefReportVisitor : public BugReporterVisitor {
   protected:
     SymbolRef Sym;
+    const CFRefCount &TF;
     const SummaryLogTy &SummaryLog;
-    bool GCEnabled;
     
   public:
-    CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log)
-       : Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {}
+    CFRefReportVisitor(SymbolRef sym, const CFRefCount &tf,
+                       const SummaryLogTy &log)
+       : Sym(sym), TF(tf), SummaryLog(log) {}
 
     virtual void Profile(llvm::FoldingSetNodeID &ID) const {
       static int x = 0;
@@ -1878,9 +1886,9 @@
 
   class CFRefLeakReportVisitor : public CFRefReportVisitor {
   public:
-    CFRefLeakReportVisitor(SymbolRef sym, bool GCEnabled,
+    CFRefLeakReportVisitor(SymbolRef sym, const CFRefCount &tf,
                            const SummaryLogTy &log)
-       : CFRefReportVisitor(sym, GCEnabled, log) {}
+       : CFRefReportVisitor(sym, tf, log) {}
 
     PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
                                     const ExplodedNode *N,
@@ -1888,24 +1896,24 @@
   };
 
   class CFRefReport : public BugReport {
-    void addGCModeDescription(const CFRefCount &TF);
-
   public:
     CFRefReport(CFRefBug &D, const CFRefCount &tf, const SummaryLogTy &log,
                 ExplodedNode *n, SymbolRef sym, bool registerVisitor = true)
       : BugReport(D, D.getDescription(), n) {
       if (registerVisitor)
-        addVisitor(new CFRefReportVisitor(sym, tf.isGCEnabled(), log));
-      addGCModeDescription(tf);
+        addVisitor(new CFRefReportVisitor(sym, tf, log));
+      addExtraTextToCFReport(*this);
     }
 
     CFRefReport(CFRefBug &D, const CFRefCount &tf, const SummaryLogTy &log,
                 ExplodedNode *n, SymbolRef sym, StringRef endText)
       : BugReport(D, D.getDescription(), endText, n) {
-      addVisitor(new CFRefReportVisitor(sym, tf.isGCEnabled(), log));
-      addGCModeDescription(tf);
+      addVisitor(new CFRefReportVisitor(sym, tf, log));
+      addExtraTextToCFReport(*this);
     }
 
+    virtual ~CFRefReport() {}
+
     virtual std::pair<ranges_iterator, ranges_iterator> getRanges() {
       const CFRefBug& BugTy = static_cast<CFRefBug&>(getBugType());
       if (!BugTy.isLeak())
@@ -1920,42 +1928,54 @@
     const MemRegion* AllocBinding;
 
   public:
-    CFRefLeakReport(CFRefBug &D, const CFRefCount &tf, const SummaryLogTy &log,
+    CFRefLeakReport(CFRefBug& D, const CFRefCount &tf, const SummaryLogTy &log,
                     ExplodedNode *n, SymbolRef sym, ExprEngine& Eng);
 
     SourceLocation getLocation() const { return AllocSite; }
   };
 } // end anonymous namespace
 
-void CFRefReport::addGCModeDescription(const CFRefCount &TF) {
-  const char *GCModeDescription;
+static const char* Msgs[] = {
+  // GC only
+  "Code is compiled to only use garbage collection",
+  // No GC.
+  "Code is compiled to use reference counts",
+  // Hybrid, with GC.
+  "Code is compiled to use either garbage collection (GC) or reference counts"
+  " (non-GC).  The bug occurs with GC enabled",
+  // Hybrid, without GC
+  "Code is compiled to use either garbage collection (GC) or reference counts"
+  " (non-GC).  The bug occurs in non-GC mode"
+};
+
+// Add the metadata text.
+static void addExtraTextToCFReport(BugReport &R) {
+  CFRefCount& TF = static_cast<CFRefBug&>(R.getBugType()).getTF();
 
   switch (TF.getLangOptions().getGCMode()) {
+  default:
+    assert(false);
+
   case LangOptions::GCOnly:
-    assert(TF.isGCEnabled());
-    GCModeDescription = "Code is compiled to only use garbage collection";
-    break;
+    assert (TF.isGCEnabled());
+    R.addExtraText(Msgs[0]);
+    return;
 
   case LangOptions::NonGC:
-    assert(!TF.isGCEnabled());
-    GCModeDescription = "Code is compiled to use reference counts";
-    break;
+    assert (!TF.isGCEnabled());
+    R.addExtraText(Msgs[1]);
+    return;
 
   case LangOptions::HybridGC:
     if (TF.isGCEnabled()) {
-      GCModeDescription = "Code is compiled to use either garbage collection "
-                          "(GC) or reference counts (non-GC).  The bug occurs "
-                          "with GC enabled";
-      break;
-    } else {
-      GCModeDescription = "Code is compiled to use either garbage collection "
-                          "(GC) or reference counts (non-GC).  The bug occurs "
-                          "in non-GC mode";
-      break;
+      R.addExtraText(Msgs[2]);
+      return;
+    }
+    else {
+      R.addExtraText(Msgs[3]);
+      return;
     }
   }
-
-  addExtraText(GCModeDescription);
 }
 
 static inline bool contains(const SmallVectorImpl<ArgEffect>& V,
@@ -2020,7 +2040,7 @@
     if (CurrV.isOwned()) {
       os << "+1 retain count";
 
-      if (GCEnabled) {
+      if (TF.isGCEnabled()) {
         assert(CurrV.getObjKind() == RetEffect::CF);
         os << ".  "
         "Core Foundation objects are not automatically garbage collected.";
@@ -2076,7 +2096,7 @@
     RefVal PrevV = *PrevT;
 
     // Specially handle -dealloc.
-    if (!GCEnabled && contains(AEffects, Dealloc)) {
+    if (!TF.isGCEnabled() && contains(AEffects, Dealloc)) {
       // Determine if the object's reference count was pushed to zero.
       assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
       // We may not have transitioned to 'release' if we hit an error.
@@ -2095,7 +2115,7 @@
       SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
       const FunctionDecl *FD = X.getAsFunctionDecl();
 
-      if (GCEnabled) {
+      if (TF.isGCEnabled()) {
         // Determine if the object's reference count was pushed to zero.
         assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
 
@@ -2146,7 +2166,7 @@
             os << " The object now has a +" << Count << " retain count.";
 
           if (PrevV.getKind() == RefVal::Released) {
-            assert(GCEnabled && CurrV.getCount() > 0);
+            assert(TF.isGCEnabled() && CurrV.getCount() > 0);
             os << " The object is not eligible for garbage collection until the "
             "retain count reaches 0 again.";
           }
@@ -2175,7 +2195,7 @@
          E=AEffects.end(); I != E; ++I) {
 
       // A bunch of things have alternate behavior under GC.
-      if (GCEnabled)
+      if (TF.isGCEnabled())
         switch (*I) {
           default: break;
           case Autorelease:
@@ -2379,7 +2399,7 @@
   return new PathDiagnosticEventPiece(L, os.str());
 }
 
-CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const CFRefCount &tf,
+CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
                                  const SummaryLogTy &log, ExplodedNode *n,
                                  SymbolRef sym, ExprEngine& Eng)
 : CFRefReport(D, tf, log, n, sym, false) {
@@ -2416,7 +2436,7 @@
   if (AllocBinding)
     os << " and stored into '" << AllocBinding->getString() << '\'';
 
-  addVisitor(new CFRefLeakReportVisitor(sym, tf.isGCEnabled(), log));
+  addVisitor(new CFRefLeakReportVisitor(sym, tf, log));
 }
 
 //===----------------------------------------------------------------------===//
@@ -3703,26 +3723,26 @@
 void CFRefCount::RegisterChecks(ExprEngine& Eng) {
   BugReporter &BR = Eng.getBugReporter();
 
-  useAfterRelease = new UseAfterRelease();
+  useAfterRelease = new UseAfterRelease(this);
   BR.Register(useAfterRelease);
 
-  releaseNotOwned = new BadRelease();
+  releaseNotOwned = new BadRelease(this);
   BR.Register(releaseNotOwned);
 
-  deallocGC = new DeallocGC();
+  deallocGC = new DeallocGC(this);
   BR.Register(deallocGC);
 
-  deallocNotOwned = new DeallocNotOwned();
+  deallocNotOwned = new DeallocNotOwned(this);
   BR.Register(deallocNotOwned);
 
-  overAutorelease = new OverAutorelease();
+  overAutorelease = new OverAutorelease(this);
   BR.Register(overAutorelease);
 
-  returnNotOwnedForOwned = new ReturnedNotOwnedForOwned();
+  returnNotOwnedForOwned = new ReturnedNotOwnedForOwned(this);
   BR.Register(returnNotOwnedForOwned);
 
   // First register "return" leaks.
-  const char *name = 0;
+  const char* name = 0;
 
   if (isGCEnabled())
     name = "Leak of returned object when using garbage collection";
@@ -3735,7 +3755,7 @@
   }
 
   // Leaks should not be reported if they are post-dominated by a sink.
-  leakAtReturn = new LeakAtReturn(name);
+  leakAtReturn = new LeakAtReturn(this, name);
   leakAtReturn->setSuppressOnSink(true);
   BR.Register(leakAtReturn);
 
@@ -3751,7 +3771,7 @@
   }
 
   // Leaks should not be reported if they are post-dominated by sinks.
-  leakWithinFunction = new LeakWithinFunction(name);
+  leakWithinFunction = new LeakWithinFunction(this, name);
   leakWithinFunction->setSuppressOnSink(true);
   BR.Register(leakWithinFunction);
 





More information about the cfe-commits mailing list