diff options
| author | Eric Christopher <echristo@apple.com> | 2011-08-24 00:39:48 +0000 | 
|---|---|---|
| committer | Eric Christopher <echristo@apple.com> | 2011-08-24 00:39:48 +0000 | 
| commit | 1825e7a26001db870090b67c0098d4383eb5a754 (patch) | |
| tree | d6b520f9062e2e23ff760835c02bce6df8755878 /clang/lib/StaticAnalyzer | |
| parent | b58b3e879d3b053dfb14342105b4b4bc27c069f3 (diff) | |
| download | bcm5719-llvm-1825e7a26001db870090b67c0098d4383eb5a754.tar.gz bcm5719-llvm-1825e7a26001db870090b67c0098d4383eb5a754.zip  | |
Revert "[analyzer] Make CFRefBug and CFRefReportVisitor not dependent on CFRefCount. Unfortunately, CFRefReport still is. No functionality change."
This reverts commit e3fb7e428b7ba0d5d902dfe3f165d70e09b03a15.
llvm-svn: 138419
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/CFRefCount.cpp | 158 | 
1 files changed, 89 insertions, 69 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CFRefCount.cpp b/clang/lib/StaticAnalyzer/Core/CFRefCount.cpp index 93f7aae94d9..2d1b822b3ec 100644 --- a/clang/lib/StaticAnalyzer/Core/CFRefCount.cpp +++ b/clang/lib/StaticAnalyzer/Core/CFRefCount.cpp @@ -1742,6 +1742,8 @@ void CFRefCount::BindingsPrinter::Print(raw_ostream &Out,  //===----------------------------------------------------------------------===//  // Error reporting.  //===----------------------------------------------------------------------===// +static void addExtraTextToCFReport(BugReport &R); +  namespace {    typedef llvm::DenseMap<const ExplodedNode *, const RetainSummary *>      SummaryLogTy; @@ -1752,30 +1754,35 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    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 @@ namespace {    };    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 @@ namespace {      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 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,      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 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,      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 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,        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 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,              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 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,           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 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,    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 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const CFRefCount &tf,    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 RetainReleaseChecker::checkDeadSymbols(SymbolReaper &SymReaper,  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 @@ void CFRefCount::RegisterChecks(ExprEngine& Eng) {    }    // 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 @@ void CFRefCount::RegisterChecks(ExprEngine& Eng) {    }    // 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);  | 

