From: Ted Kremenek Date: Wed, 25 Feb 2009 02:54:57 +0000 (+0000) Subject: retain/release checker: Implement basic tracking of autorelease stack. Next thing... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6c4becbab5953c84438d1fe829316b45f7df3453;p=clang retain/release checker: Implement basic tracking of autorelease stack. Next thing is to wire up pools with their contents. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65425 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 652b65f648..70d473b019 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -646,6 +646,13 @@ private: ObjCMethodSummaries[S] = Summ; } + void addInstMethSummary(const char* Cls, const char* nullaryName, + RetainSummary *Summ) { + IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); + Selector S = GetNullarySelector(nullaryName, Ctx); + ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; + } + void addInstMethSummary(const char* Cls, RetainSummary* Summ, va_list argp) { IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); @@ -1134,10 +1141,9 @@ void RetainSummaryManager::InitializeMethodSummaries() { addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ); // Specially handle NSAutoreleasePool. - addInstMethSummary("NSAutoreleasePool", + addInstMethSummary("NSAutoreleasePool", "init", getPersistentSummary(RetEffect::MakeReceiverAlias(), - NewAutoreleasePool), - "init", NULL); + NewAutoreleasePool)); // For NSWindow, allocated objects are (initially) self-owned. // FIXME: For now we opt for false negatives with NSWindow, as these objects @@ -1369,10 +1375,10 @@ static int AutoRCIndex = 0; static int AutoRBIndex = 0; namespace { class VISIBILITY_HIDDEN AutoreleasePoolContents {}; } -namespace { class VISIBILITY_HIDDEN AutoreleaseBindings {}; } +namespace { class VISIBILITY_HIDDEN AutoreleaseStack {}; } namespace clang { -template<> struct GRStateTrait +template<> struct GRStateTrait : public GRStatePartialTrait { static inline void* GDMIndex() { return &AutoRBIndex; } }; @@ -1522,6 +1528,17 @@ void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state, (*I).second.print(Out); Out << nl; } + + // Print the autorelease stack. + ARStack stack = state->get(); + 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; + } } static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) { @@ -2067,7 +2084,10 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym, } // Fall-through. - case NewAutoreleasePool: // FIXME: Implement pushing the pool to the stack. + case NewAutoreleasePool: + assert(!isGCEnabled()); + return state.add(sym); + case DoNothingByRef: case DoNothing: if (!isGCEnabled() && V.getKind() == RefVal::Released) {