[cfe-commits] r138426 - /cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
Jordy Rose
jediknil at belkadan.com
Tue Aug 23 22:47:39 PDT 2011
Author: jrose
Date: Wed Aug 24 00:47:39 2011
New Revision: 138426
URL: http://llvm.org/viewvc/llvm-project?rev=138426&view=rev
Log:
[analyzer] Reapply 138382 and 138388 (reverted in 138419 and 138420). The issue seems to have been with the uninitialized variable fixed in 138424; a fix for another Heisencrasher coming soon.
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=138426&r1=138425&r2=138426&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Wed Aug 24 00:47:39 2011
@@ -1742,8 +1742,6 @@
//===----------------------------------------------------------------------===//
// Error reporting.
//===----------------------------------------------------------------------===//
-static void addExtraTextToCFReport(BugReport &R);
-
namespace {
typedef llvm::DenseMap<const ExplodedNode *, const RetainSummary *>
SummaryLogTy;
@@ -1754,35 +1752,30 @@
class CFRefBug : public BugType {
protected:
- CFRefCount& TF;
-
- CFRefBug(CFRefCount* tf, StringRef name)
- : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}
+ CFRefBug(StringRef name)
+ : BugType(name, "Memory (Core Foundation/Objective-C)") {}
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(CFRefCount* tf)
- : CFRefBug(tf, "Use-after-release") {}
+ UseAfterRelease() : CFRefBug("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(CFRefCount* tf) : CFRefBug(tf, "Bad release") {}
+ BadRelease() : CFRefBug("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";
}
@@ -1790,8 +1783,8 @@
class DeallocGC : public CFRefBug {
public:
- DeallocGC(CFRefCount *tf)
- : CFRefBug(tf, "-dealloc called while using garbage collection") {}
+ DeallocGC()
+ : CFRefBug("-dealloc called while using garbage collection") {}
const char *getDescription() const {
return "-dealloc called while using garbage collection";
@@ -1800,8 +1793,8 @@
class DeallocNotOwned : public CFRefBug {
public:
- DeallocNotOwned(CFRefCount *tf)
- : CFRefBug(tf, "-dealloc sent to non-exclusively owned object") {}
+ DeallocNotOwned()
+ : CFRefBug("-dealloc sent to non-exclusively owned object") {}
const char *getDescription() const {
return "-dealloc sent to object that may be referenced elsewhere";
@@ -1810,8 +1803,8 @@
class OverAutorelease : public CFRefBug {
public:
- OverAutorelease(CFRefCount *tf) :
- CFRefBug(tf, "Object sent -autorelease too many times") {}
+ OverAutorelease()
+ : CFRefBug("Object sent -autorelease too many times") {}
const char *getDescription() const {
return "Object sent -autorelease too many times";
@@ -1820,8 +1813,8 @@
class ReturnedNotOwnedForOwned : public CFRefBug {
public:
- ReturnedNotOwnedForOwned(CFRefCount *tf) :
- CFRefBug(tf, "Method should return an owned object") {}
+ ReturnedNotOwnedForOwned()
+ : CFRefBug("Method should return an owned object") {}
const char *getDescription() const {
return "Object with a +0 retain count returned to caller where a +1 "
@@ -1832,25 +1825,25 @@
class Leak : public CFRefBug {
const bool isReturn;
protected:
- Leak(CFRefCount* tf, StringRef name, bool isRet)
- : CFRefBug(tf, name), isReturn(isRet) {}
+ Leak(StringRef name, bool isRet)
+ : CFRefBug(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(CFRefCount* tf, StringRef name)
- : Leak(tf, name, true) {}
+ LeakAtReturn(StringRef name)
+ : Leak(name, true) {}
};
class LeakWithinFunction : public Leak {
public:
- LeakWithinFunction(CFRefCount* tf, StringRef name)
- : Leak(tf, name, false) {}
+ LeakWithinFunction(StringRef name)
+ : Leak(name, false) {}
};
//===---------===//
@@ -1860,13 +1853,12 @@
class CFRefReportVisitor : public BugReporterVisitor {
protected:
SymbolRef Sym;
- const CFRefCount &TF;
const SummaryLogTy &SummaryLog;
+ bool GCEnabled;
public:
- CFRefReportVisitor(SymbolRef sym, const CFRefCount &tf,
- const SummaryLogTy &log)
- : Sym(sym), TF(tf), SummaryLog(log) {}
+ CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log)
+ : Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {}
virtual void Profile(llvm::FoldingSetNodeID &ID) const {
static int x = 0;
@@ -1886,9 +1878,9 @@
class CFRefLeakReportVisitor : public CFRefReportVisitor {
public:
- CFRefLeakReportVisitor(SymbolRef sym, const CFRefCount &tf,
+ CFRefLeakReportVisitor(SymbolRef sym, bool GCEnabled,
const SummaryLogTy &log)
- : CFRefReportVisitor(sym, tf, log) {}
+ : CFRefReportVisitor(sym, GCEnabled, log) {}
PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
@@ -1896,24 +1888,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, log));
- addExtraTextToCFReport(*this);
+ addVisitor(new CFRefReportVisitor(sym, tf.isGCEnabled(), log));
+ addGCModeDescription(tf);
}
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, log));
- addExtraTextToCFReport(*this);
+ addVisitor(new CFRefReportVisitor(sym, tf.isGCEnabled(), log));
+ addGCModeDescription(tf);
}
- virtual ~CFRefReport() {}
-
virtual std::pair<ranges_iterator, ranges_iterator> getRanges() {
const CFRefBug& BugTy = static_cast<CFRefBug&>(getBugType());
if (!BugTy.isLeak())
@@ -1928,54 +1920,42 @@
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
-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();
+void CFRefReport::addGCModeDescription(const CFRefCount &TF) {
+ const char *GCModeDescription;
switch (TF.getLangOptions().getGCMode()) {
- default:
- assert(false);
-
case LangOptions::GCOnly:
- assert (TF.isGCEnabled());
- R.addExtraText(Msgs[0]);
- return;
+ assert(TF.isGCEnabled());
+ GCModeDescription = "Code is compiled to only use garbage collection";
+ break;
case LangOptions::NonGC:
- assert (!TF.isGCEnabled());
- R.addExtraText(Msgs[1]);
- return;
+ assert(!TF.isGCEnabled());
+ GCModeDescription = "Code is compiled to use reference counts";
+ break;
case LangOptions::HybridGC:
if (TF.isGCEnabled()) {
- R.addExtraText(Msgs[2]);
- return;
- }
- else {
- R.addExtraText(Msgs[3]);
- return;
+ 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;
}
}
+
+ addExtraText(GCModeDescription);
}
static inline bool contains(const SmallVectorImpl<ArgEffect>& V,
@@ -2040,7 +2020,7 @@
if (CurrV.isOwned()) {
os << "+1 retain count";
- if (TF.isGCEnabled()) {
+ if (GCEnabled) {
assert(CurrV.getObjKind() == RetEffect::CF);
os << ". "
"Core Foundation objects are not automatically garbage collected.";
@@ -2096,7 +2076,7 @@
RefVal PrevV = *PrevT;
// Specially handle -dealloc.
- if (!TF.isGCEnabled() && contains(AEffects, Dealloc)) {
+ if (!GCEnabled && 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.
@@ -2115,7 +2095,7 @@
SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
const FunctionDecl *FD = X.getAsFunctionDecl();
- if (TF.isGCEnabled()) {
+ if (GCEnabled) {
// Determine if the object's reference count was pushed to zero.
assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
@@ -2166,7 +2146,7 @@
os << " The object now has a +" << Count << " retain count.";
if (PrevV.getKind() == RefVal::Released) {
- assert(TF.isGCEnabled() && CurrV.getCount() > 0);
+ assert(GCEnabled && CurrV.getCount() > 0);
os << " The object is not eligible for garbage collection until the "
"retain count reaches 0 again.";
}
@@ -2195,7 +2175,7 @@
E=AEffects.end(); I != E; ++I) {
// A bunch of things have alternate behavior under GC.
- if (TF.isGCEnabled())
+ if (GCEnabled)
switch (*I) {
default: break;
case Autorelease:
@@ -2399,7 +2379,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) {
@@ -2436,7 +2416,7 @@
if (AllocBinding)
os << " and stored into '" << AllocBinding->getString() << '\'';
- addVisitor(new CFRefLeakReportVisitor(sym, tf, log));
+ addVisitor(new CFRefLeakReportVisitor(sym, tf.isGCEnabled(), log));
}
//===----------------------------------------------------------------------===//
@@ -2963,9 +2943,6 @@
const CallOrObjCMessage &CallOrMsg,
InstanceReceiver Receiver,
CheckerContext &C) const {
- // FIXME: This goes away when the RetainSummaryManager moves to the checker.
- CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
-
const ProgramState *state = C.getState();
// Evaluate the effect of the arguments.
@@ -3013,10 +2990,13 @@
RetEffect RE = Summ.getRetEffect();
if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
- if (ReceiverIsTracked)
- RE = TF.Summaries.getObjAllocRetEffect();
- else
+ if (ReceiverIsTracked) {
+ // FIXME: This goes away if the RetainSummaryManager moves to the checker.
+ CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
+ RE = TF.Summaries.getObjAllocRetEffect();
+ } else {
RE = RetEffect::MakeNoRet();
+ }
}
switch (RE.getKind()) {
@@ -3399,17 +3379,12 @@
if (!Pred)
return;
- ExprEngine &Eng = C.getEngine();
- // FIXME: This goes away once HandleAutoreleaseCount() and the
- // RetainSummariesManager move to RetainReleaseChecker.
- CFRefCount &TF = static_cast<CFRefCount&>(Eng.getTF());
-
// Update the autorelease counts.
static SimpleProgramPointTag
AutoreleaseTag("RetainReleaseChecker : Autorelease");
GenericNodeBuilderRefCount Bd(C.getNodeBuilder(), S, &AutoreleaseTag);
- llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, Eng,
- Sym, X);
+ llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred,
+ C.getEngine(), Sym, X);
// Did we cache out?
if (!Pred)
@@ -3423,6 +3398,9 @@
// Consult the summary of the enclosing method.
const Decl *CD = &Pred->getCodeDecl();
+ // FIXME: This goes away once the RetainSummariesManager moves to the checker.
+ CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
+
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
// Unlike regular functions, /all/ ObjC methods are assumed to always
// follow Cocoa retain-count conventions, not just those with special
@@ -3725,26 +3703,26 @@
void CFRefCount::RegisterChecks(ExprEngine& Eng) {
BugReporter &BR = Eng.getBugReporter();
- useAfterRelease = new UseAfterRelease(this);
+ useAfterRelease = new UseAfterRelease();
BR.Register(useAfterRelease);
- releaseNotOwned = new BadRelease(this);
+ releaseNotOwned = new BadRelease();
BR.Register(releaseNotOwned);
- deallocGC = new DeallocGC(this);
+ deallocGC = new DeallocGC();
BR.Register(deallocGC);
- deallocNotOwned = new DeallocNotOwned(this);
+ deallocNotOwned = new DeallocNotOwned();
BR.Register(deallocNotOwned);
- overAutorelease = new OverAutorelease(this);
+ overAutorelease = new OverAutorelease();
BR.Register(overAutorelease);
- returnNotOwnedForOwned = new ReturnedNotOwnedForOwned(this);
+ returnNotOwnedForOwned = new ReturnedNotOwnedForOwned();
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";
@@ -3757,7 +3735,7 @@
}
// Leaks should not be reported if they are post-dominated by a sink.
- leakAtReturn = new LeakAtReturn(this, name);
+ leakAtReturn = new LeakAtReturn(name);
leakAtReturn->setSuppressOnSink(true);
BR.Register(leakAtReturn);
@@ -3773,7 +3751,7 @@
}
// Leaks should not be reported if they are post-dominated by sinks.
- leakWithinFunction = new LeakWithinFunction(this, name);
+ leakWithinFunction = new LeakWithinFunction(name);
leakWithinFunction->setSuppressOnSink(true);
BR.Register(leakWithinFunction);
More information about the cfe-commits
mailing list