summaryrefslogtreecommitdiffstats
path: root/clang/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-11 18:14:09 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-11 18:14:09 +0000
commite5605568aed396b9ec4fb0eb223cd2e609b40845 (patch)
treee516d8191bf077b15ca2144cd10893bfe8886eac /clang/Analysis/CFRefCount.cpp
parent70c238a1d88f4442c1dc84efdc9a8b4d889ebde8 (diff)
downloadbcm5719-llvm-e5605568aed396b9ec4fb0eb223cd2e609b40845.tar.gz
bcm5719-llvm-e5605568aed396b9ec4fb0eb223cd2e609b40845.zip
Added bookkeeping of error nodes.
llvm-svn: 48234
Diffstat (limited to 'clang/Analysis/CFRefCount.cpp')
-rw-r--r--clang/Analysis/CFRefCount.cpp44
1 files changed, 34 insertions, 10 deletions
diff --git a/clang/Analysis/CFRefCount.cpp b/clang/Analysis/CFRefCount.cpp
index 08399420e54..e51353a61dc 100644
--- a/clang/Analysis/CFRefCount.cpp
+++ b/clang/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<SymbolID, RefVal> RefBindings;
typedef RefBindings::Factory RefBFactoryTy;
-
+
+ typedef llvm::SmallPtrSet<GRExprEngine::NodeTy*,2> UseAfterReleasesTy;
+ typedef llvm::SmallPtrSet<GRExprEngine::NodeTy*,2> 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<ValueState>& 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<ValueState>& 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;
}
}
OpenPOWER on IntegriCloud