[cfe-commits] r67384 - /cfe/trunk/lib/Analysis/CFRefCount.cpp
Ted Kremenek
kremenek at apple.com
Fri Mar 20 10:34:15 PDT 2009
Author: kremenek
Date: Fri Mar 20 12:34:15 2009
New Revision: 67384
URL: http://llvm.org/viewvc/llvm-project?rev=67384&view=rev
Log:
retain/release checker: Tracking autorelease counts for objects. We're still not
completely there with accurately modeling autorelease pools.
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=67384&r1=67383&r2=67384&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Mar 20 12:34:15 2009
@@ -1440,6 +1440,28 @@
};
} // end clang namespace
+static SymbolRef GetCurrentAutoreleasePool(const GRState* state) {
+ ARStack stack = state->get<AutoreleaseStack>();
+ return stack.isEmpty() ? SymbolRef() : stack.getHead();
+}
+
+static GRStateRef SendAutorelease(GRStateRef state, ARCounts::Factory &F,
+ SymbolRef sym) {
+
+ SymbolRef pool = GetCurrentAutoreleasePool(state);
+ const ARCounts *cnts = state.get<AutoreleasePoolContents>(pool);
+ ARCounts newCnts(0);
+
+ if (cnts) {
+ const unsigned *cnt = (*cnts).lookup(sym);
+ newCnts = F.Add(*cnts, sym, cnt ? *cnt + 1 : 1);
+ }
+ else
+ newCnts = F.Add(F.GetEmptyMap(), sym, 1);
+
+ return state.set<AutoreleasePoolContents>(pool, newCnts);
+}
+
//===----------------------------------------------------------------------===//
// Transfer functions.
//===----------------------------------------------------------------------===//
@@ -1567,9 +1589,26 @@
} // end anonymous namespace
+static void PrintPool(std::ostream &Out, SymbolRef Sym, const GRState *state) {
+ Out << ' ';
+ if (Sym.isValid())
+ Out << Sym;
+ else
+ Out << "<pool>";
+ Out << ":{";
+
+ // Get the contents of the pool.
+ if (const ARCounts *cnts = state->get<AutoreleasePoolContents>(Sym))
+ for (ARCounts::iterator J=cnts->begin(), EJ=cnts->end(); J != EJ; ++J)
+ Out << '(' << J.getKey() << ',' << J.getData() << ')';
+
+ Out << '}';
+}
void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
const char* nl, const char* sep) {
+
+
RefBindings B = state->get<RefBindings>();
@@ -1583,15 +1622,14 @@
}
// Print the autorelease stack.
+ Out << sep << nl << "AR pool stack:";
ARStack stack = state->get<AutoreleaseStack>();
- if (!stack.isEmpty()) {
- Out << sep << nl << "AR pool stack:";
- for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
- Out << ' ' << (*I);
-
- Out << nl;
- }
+ PrintPool(Out, SymbolRef(), state); // Print the caller's pool.
+ for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
+ PrintPool(Out, *I, state);
+
+ Out << nl;
}
static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) {
@@ -2230,6 +2268,9 @@
case Autorelease:
if (isGCEnabled())
return state;
+
+ // Update the autorelease counts.
+ state = SendAutorelease(state, ARCountFactory, sym);
// Fall-through.
More information about the cfe-commits
mailing list