Simplify CF ref. count checker state machine.

llvm-svn: 49505
This commit is contained in:
Ted Kremenek 2008-04-10 23:09:18 +00:00
parent 9b5ffc8408
commit 3c03d52d6e
1 changed files with 36 additions and 31 deletions

View File

@ -457,22 +457,27 @@ class VISIBILITY_HIDDEN RefVal {
} }
public: public:
enum Kind { Owned = 0, AcqOwned = 1, NotOwned = 2, Released = 3, enum Kind { Owned = 0, NotOwned = 1, Released = 2,
ErrorUseAfterRelease = 4, ErrorReleaseNotOwned = 5 }; ErrorUseAfterRelease = 3, ErrorReleaseNotOwned = 4 };
Kind getKind() const { return (Kind) (Data & 0x5); } Kind getKind() const { return (Kind) (Data & 0x7); }
unsigned getCount() const { unsigned getCount() const {
assert (getKind() == Owned || getKind() == AcqOwned); assert (getKind() == Owned || getKind() == NotOwned);
return Data >> 3; return Data >> 3;
} }
static bool isError(Kind k) { return k >= ErrorUseAfterRelease; } static bool isError(Kind k) { return k >= ErrorUseAfterRelease; }
static RefVal makeOwned(unsigned Count) { return RefVal(Owned, Count); } static RefVal makeOwned(unsigned Count = 0) {
static RefVal makeAcqOwned(unsigned Count) { return RefVal(AcqOwned, Count); } return RefVal(Owned, Count);
static RefVal makeNotOwned() { return RefVal(NotOwned); } }
static RefVal makeNotOwned(unsigned Count = 0) {
return RefVal(NotOwned, Count);
}
static RefVal makeReleased() { return RefVal(Released); } static RefVal makeReleased() { return RefVal(Released); }
static RefVal makeUseAfterRelease() { return RefVal(ErrorUseAfterRelease); } static RefVal makeUseAfterRelease() { return RefVal(ErrorUseAfterRelease); }
static RefVal makeReleaseNotOwned() { return RefVal(ErrorReleaseNotOwned); } static RefVal makeReleaseNotOwned() { return RefVal(ErrorReleaseNotOwned); }
@ -486,17 +491,19 @@ public:
void RefVal::print(std::ostream& Out) const { void RefVal::print(std::ostream& Out) const {
switch (getKind()) { switch (getKind()) {
default: assert(false); default: assert(false);
case Owned: case Owned: {
Out << "Owned(" << getCount() << ")"; Out << "Owned";
unsigned cnt = getCount();
if (cnt) Out << " (+ " << cnt << ")";
break; break;
}
case AcqOwned: case NotOwned: {
Out << "Acquired-Owned(" << getCount() << ")";
break;
case NotOwned:
Out << "Not-Owned"; Out << "Not-Owned";
unsigned cnt = getCount();
if (cnt) Out << " (+ " << cnt << ")";
break; break;
}
case Released: case Released:
Out << "Released"; Out << "Released";
@ -748,7 +755,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
ValueState StImpl = *St; ValueState StImpl = *St;
RefBindings B = GetRefBindings(StImpl); RefBindings B = GetRefBindings(StImpl);
SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(1))); SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned()));
St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl), St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
CE, lval::SymbolVal(Sym), CE, lval::SymbolVal(Sym),
@ -804,13 +811,9 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
case RefVal::Owned: case RefVal::Owned:
V = RefVal::makeOwned(V.getCount()+1); break; V = RefVal::makeOwned(V.getCount()+1); break;
case RefVal::AcqOwned:
V = RefVal::makeAcqOwned(V.getCount()+1);
break;
case RefVal::NotOwned: case RefVal::NotOwned:
V = RefVal::makeAcqOwned(1); V = RefVal::makeNotOwned(V.getCount()+1);
break; break;
case RefVal::Released: case RefVal::Released:
@ -825,21 +828,23 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
assert (false); assert (false);
case RefVal::Owned: { case RefVal::Owned: {
unsigned Count = V.getCount() - 1; signed Count = ((signed) V.getCount()) - 1;
V = Count ? RefVal::makeOwned(Count) : RefVal::makeReleased(); V = Count >= 0 ? RefVal::makeOwned(Count) : RefVal::makeReleased();
break; break;
} }
case RefVal::AcqOwned: { case RefVal::NotOwned: {
unsigned Count = V.getCount() - 1; signed Count = ((signed) V.getCount()) - 1;
V = Count ? RefVal::makeAcqOwned(Count) : RefVal::makeNotOwned();
if (Count >= 0)
V = RefVal::makeNotOwned(Count);
else {
V = RefVal::makeReleaseNotOwned();
hasError = V.getKind();
}
break; break;
} }
case RefVal::NotOwned:
V = RefVal::makeReleaseNotOwned();
hasError = V.getKind();
break;
case RefVal::Released: case RefVal::Released:
V = RefVal::makeUseAfterRelease(); V = RefVal::makeUseAfterRelease();