[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