diff options
| author | Ted Kremenek <kremenek@apple.com> | 2009-02-23 17:45:03 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2009-02-23 17:45:03 +0000 |
| commit | 50db3d0923e3307736e71d9c6891d16790eb2b54 (patch) | |
| tree | 3d0840d1987e50ca0711bf62e09d534d83adddbf /clang/lib | |
| parent | 7df3a5aec36423f5b2f08e53ab05137d8b379975 (diff) | |
| download | bcm5719-llvm-50db3d0923e3307736e71d9c6891d16790eb2b54.tar.gz bcm5719-llvm-50db3d0923e3307736e71d9c6891d16790eb2b54.zip | |
Add more boilerplate logic to more accurately reason about autorelease pools.
This doesn't change the current functionality, but better codifies the
autorelease pool stack itself.
llvm-svn: 65328
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Analysis/CFRefCount.cpp | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 39edcfd8ad8..5a3e9be0cb3 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -221,7 +221,8 @@ enum ArgEffect { IncRefMsg, IncRef, DecRefMsg, DecRef, MakeCollectable, DoNothing, DoNothingByRef, - StopTracking, MayEscape, SelfOwn, Autorelease }; + StopTracking, MayEscape, SelfOwn, Autorelease, + NewAutoreleasePool }; /// ArgEffects summarizes the effects of a function/method call on all of /// its arguments. @@ -1132,6 +1133,12 @@ void RetainSummaryManager::InitializeMethodSummaries() { Summ = getPersistentSummary(E, Autorelease); addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ); + // Specially handle NSAutoreleasePool. + addInstMethSummary("NSAutoreleasePool", + getPersistentSummary(RetEffect::MakeReceiverAlias(), + NewAutoreleasePool), + "init", NULL); + // For NSWindow, allocated objects are (initially) self-owned. // FIXME: For now we opt for false negatives with NSWindow, as these objects // self-own themselves. However, they only do this once they are displayed. @@ -1354,13 +1361,50 @@ namespace clang { // ARBindings - State used to track objects in autorelease pools. //===----------------------------------------------------------------------===// -typedef llvm::ImmutableSet<SymbolRef> ARPoolContents; -typedef llvm::ImmutableList< std::pair<SymbolRef, ARPoolContents*> > ARBindings; + +namespace { +class VISIBILITY_HIDDEN AutoreleasePoolID { + unsigned short PoolLevel; + SymbolRef Sym; + +public: + AutoreleasePoolID() : PoolLevel(0) {} + AutoreleasePoolID(unsigned short poolLevel, SymbolRef sym) + : PoolLevel(poolLevel), Sym(Sym) {} + + bool operator<(const AutoreleasePoolID &X) const { + assert(!(PoolLevel == X.PoolLevel) || Sym == X.Sym); + return PoolLevel < X.PoolLevel; + } + + bool operator==(const AutoreleasePoolID &X) const { + assert(!(PoolLevel == X.PoolLevel) || Sym == X.Sym); + return PoolLevel == X.PoolLevel; + } + + bool matches(SymbolRef sym) { + return Sym.isInitialized() ? Sym == sym : false; + } + + static void Profile(llvm::FoldingSetNodeID& ID, const AutoreleasePoolID& AI) { + ID.AddInteger(AI.PoolLevel); + if (AI.Sym.isInitialized()) ID.Add(AI.Sym); + } +}; +} + +typedef llvm::ImmutableSet<SymbolRef> AutoreleasePoolContents; +typedef llvm::ImmutableMap<AutoreleasePoolID, AutoreleasePoolContents> + AutoreleaseBindings; + static int AutoRBIndex = 0; +// We can use 'AutoreleaseBindings' directly as the tag class into the GDM sinc +// it is an ImmutableMap based on two types private to this source file. namespace clang { template<> - struct GRStateTrait<ARBindings> : public GRStatePartialTrait<ARBindings> { + struct GRStateTrait<AutoreleaseBindings> + : public GRStatePartialTrait<AutoreleaseBindings> { static inline void* GDMIndex() { return &AutoRBIndex; } }; } @@ -2040,6 +2084,8 @@ RefBindings CFRefCount::Update(RefBindings B, SymbolRef sym, case IncRefMsg: E = isGCEnabled() ? DoNothing : IncRef; break; case DecRefMsg: E = isGCEnabled() ? DoNothing : DecRef; break; case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break; + case NewAutoreleasePool: E = isGCEnabled() ? DoNothing : + NewAutoreleasePool; break; } switch (E) { @@ -2052,6 +2098,8 @@ RefBindings CFRefCount::Update(RefBindings B, SymbolRef sym, break; } // Fall-through. + + case NewAutoreleasePool: // FIXME: Implement pushing the pool to the stack. case DoNothingByRef: case DoNothing: if (!isGCEnabled() && V.getKind() == RefVal::Released) { |

