From: Ted Kremenek Date: Tue, 11 Mar 2008 18:14:09 +0000 (+0000) Subject: Added bookkeeping of error nodes. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73c750b6feea2d284ec1c074952dddea84d172bb;p=clang Added bookkeeping of error nodes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48234 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/CFRefCount.cpp b/Analysis/CFRefCount.cpp index 08399420e5..e51353a61d 100644 --- a/Analysis/CFRefCount.cpp +++ b/Analysis/CFRefCount.cpp @@ -182,6 +182,8 @@ public: return Data >> 3; } + static bool isError(Kind k) { return k >= ErrorUseAfterRelease; } + static RefVal makeOwned(unsigned Count) { return RefVal(Owned, Count); } static RefVal makeAcqOwned(unsigned Count) { return RefVal(AcqOwned, Count); } static RefVal makeNotOwned() { return RefVal(NotOwned); } @@ -197,9 +199,16 @@ public: class CFRefCount : public GRSimpleVals { typedef llvm::ImmutableMap RefBindings; typedef RefBindings::Factory RefBFactoryTy; - + + typedef llvm::SmallPtrSet UseAfterReleasesTy; + typedef llvm::SmallPtrSet ReleasesNotOwnedTy; + CFRefSummaryManager Summaries; RefBFactoryTy RefBFactory; + + UseAfterReleasesTy UseAfterReleases; + ReleasesNotOwnedTy ReleasesNotOwned; + static RefBindings GetRefBindings(ValueState& StImpl) { return RefBindings((RefBindings::TreeTy*) StImpl.CheckerState); @@ -214,7 +223,7 @@ class CFRefCount : public GRSimpleVals { } RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, - bool& hasError); + RefVal::Kind& hasError); public: CFRefCount() {} @@ -258,7 +267,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst, // Evaluate the effects of the call. ValueState StVals = *St; - bool hasError = false; + RefVal::Kind hasError = (RefVal::Kind) 0; if (!Summ) { @@ -310,16 +319,31 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst, St = StateMgr.getPersistentState(StVals); if (hasError) { - + GRExprEngine::NodeTy* N = Builder.generateNode(CE, St, Pred); + + if (N) { + N->markAsSink(); + + switch (hasError) { + default: assert(false); + case RefVal::ErrorUseAfterRelease: + UseAfterReleases.insert(N); + break; + + case RefVal::ErrorReleaseNotOwned: + ReleasesNotOwned.insert(N); + break; + } + } } - - Builder.Nodify(Dst, CE, Pred, St); + else + Builder.Nodify(Dst, CE, Pred, St); } CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, - bool& hasError) { + RefVal::Kind& hasError) { // FIXME: This dispatch can potentially be sped up by unifiying it into // a single switch statement. Opt for simplicity for now. @@ -348,8 +372,8 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, break; case RefVal::Released: - hasError = true; V = RefVal::makeUseAfterRelease(); + hasError = V.getKind(); break; } @@ -371,13 +395,13 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, } case RefVal::NotOwned: - hasError = true; V = RefVal::makeReleaseNotOwned(); + hasError = V.getKind(); break; case RefVal::Released: - hasError = true; V = RefVal::makeUseAfterRelease(); + hasError = V.getKind(); break; } }