[cfe-commits] r50512 - /cfe/trunk/lib/Analysis/CFRefCount.cpp
Ted Kremenek
kremenek at apple.com
Wed Apr 30 19:18:37 PDT 2008
Author: kremenek
Date: Wed Apr 30 21:18:37 2008
New Revision: 50512
URL: http://llvm.org/viewvc/llvm-project?rev=50512&view=rev
Log:
Added support for "autorelease" message in CF ref. count checker.
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=50512&r1=50511&r2=50512&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed Apr 30 21:18:37 2008
@@ -637,6 +637,7 @@
Selector RetainSelector;
Selector ReleaseSelector;
+ Selector AutoreleaseSelector;
public:
@@ -677,7 +678,8 @@
GCEnabled(gcenabled),
LOpts(lopts),
RetainSelector(GetUnarySelector("retain", Ctx)),
- ReleaseSelector(GetUnarySelector("release", Ctx)) {}
+ ReleaseSelector(GetUnarySelector("release", Ctx)),
+ AutoreleaseSelector(GetUnarySelector("autorelease", Ctx)) {}
virtual ~CFRefCount() {
for (LeaksTy::iterator I = Leaks.begin(), E = Leaks.end(); I!=E; ++I)
@@ -989,43 +991,68 @@
if (!Receiver)
return true;
- // Check if we are calling "Retain" or "Release".
+ // Check if we are calling "autorelease".
+
+ enum { IsRelease, IsRetain, IsAutorelease, IsNone } mode = IsNone;
- bool isRetain = false;
+ if (S == AutoreleaseSelector)
+ mode = IsAutorelease;
+ else if (S == RetainSelector)
+ mode = IsRetain;
+ else if (S == ReleaseSelector)
+ mode = IsRelease;
- if (S == RetainSelector)
- isRetain = true;
- else if (S != ReleaseSelector)
+ if (mode == IsNone)
return true;
- // We have "Retain" or "Release". Get the reference binding.
-
+ // We have "retain", "release", or "autorelease".
ValueStateManager& StateMgr = Eng.getStateManager();
ValueState* St = Builder.GetState(Pred);
RVal V = StateMgr.GetRVal(St, Receiver);
+ // Was the argument something we are not tracking?
if (!isa<lval::SymbolVal>(V))
return true;
+ // Get the bindings.
SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
RefBindings B = GetRefBindings(*St);
+ // Find the tracked value.
RefBindings::TreeTy* T = B.SlimFind(Sym);
-
+
if (!T)
return true;
-
- RefVal::Kind hasErr = (RefVal::Kind) 0;
- B = Update(B, Sym, T->getValue().second, isRetain ? IncRef : DecRef, hasErr);
- // Create a new state with the updated bindings.
+ RefVal::Kind hasErr = (RefVal::Kind) 0;
+ // Update the bindings.
+ switch (mode) {
+ case IsNone:
+ assert(false);
+
+ case IsRelease:
+ B = Update(B, Sym, T->getValue().second, DecRef, hasErr);
+ break;
+
+ case IsRetain:
+ B = Update(B, Sym, T->getValue().second, IncRef, hasErr);
+ break;
+
+ case IsAutorelease:
+ // For now we just stop tracking a value if we see
+ // it sent "autorelease." In the future we can potentially
+ // track the associated pool.
+ B = Remove(B, Sym);
+ break;
+ }
+
+ // Create a new state with the updated bindings.
ValueState StVals = *St;
SetRefBindings(StVals, B);
St = StateMgr.getPersistentState(StVals);
- // Create an error node if it exists.
-
+ // Create an error node if it exists.
if (hasErr)
ProcessNonLeakError(Dst, Builder, ME, Receiver, Pred, St, hasErr, Sym);
else
More information about the cfe-commits
mailing list