diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-16 20:40:59 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-16 20:40:59 +0000 |
commit | 1392261ff4418a070fb919cb4832b76b468b6faa (patch) | |
tree | 2a20b44e37318f987d50f88db3ee660b83719162 /lib/Analysis/CFRefCount.cpp | |
parent | a8f582d759d293da8a61a9e28ad2b79dd493e261 (diff) |
Small tweaks to EvalStore: pass an "RVal" instead of "LVal" for the TargetLV to
represent possible stores to "Unknown."
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49811 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 332533557f..94a502a9b6 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -455,14 +455,9 @@ namespace { } // end anonymous namespace //===----------------------------------------------------------------------===// -// Transfer functions. +// Reference-counting logic (typestate + counts). //===----------------------------------------------------------------------===// -static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) { - IdentifierInfo* II = &Ctx.Idents.get(name); - return Ctx.Selectors.getSelector(0, &II); -} - namespace { class VISIBILITY_HIDDEN RefVal { @@ -543,6 +538,15 @@ void RefVal::print(std::ostream& Out) const { } } +//===----------------------------------------------------------------------===// +// Transfer functions. +//===----------------------------------------------------------------------===// + +static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) { + IdentifierInfo* II = &Ctx.Idents.get(name); + return Ctx.Selectors.getSelector(0, &II); +} + class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals { // Type definitions. @@ -597,6 +601,7 @@ class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals { RefVal::Kind hasErr); public: + CFRefCount(ASTContext& Ctx) : Summaries(Ctx), RetainSelector(GetUnarySelector("retain", Ctx)), @@ -630,6 +635,13 @@ public: ObjCMessageExpr* ME, ExplodedNode<ValueState>* Pred); + // Stores. + + virtual void EvalStore(ExplodedNodeSet<ValueState>& Dst, + GRExprEngine& Engine, + GRStmtNodeBuilder<ValueState>& Builder, + Expr* E, ExplodedNode<ValueState>* Pred, + ValueState* St, RVal TargetLV, RVal Val); // End-of-path. virtual void EvalEndPath(GRExprEngine& Engine, @@ -916,6 +928,49 @@ bool CFRefCount::EvalObjCMessageExprAux(ExplodedNodeSet<ValueState>& Dst, return false; } +// Stores. + +void CFRefCount::EvalStore(ExplodedNodeSet<ValueState>& Dst, + GRExprEngine& Eng, + GRStmtNodeBuilder<ValueState>& Builder, + Expr* E, ExplodedNode<ValueState>* Pred, + ValueState* St, RVal TargetLV, RVal Val) { + + // Check if we have a binding for "Val" and if we are storing it to something + // we don't understand or otherwise the value "escapes" the function. + + if (!isa<lval::SymbolVal>(Val)) + return; + + // Are we storing to something that causes the value to "escape"? + + bool escapes = false; + + if (!isa<lval::DeclVal>(TargetLV)) + escapes = true; + else + escapes = cast<lval::DeclVal>(TargetLV).getDecl()->hasGlobalStorage(); + + if (!escapes) + return; + + SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol(); + RefBindings B = GetRefBindings(*St); + RefBindings::TreeTy* T = B.SlimFind(Sym); + + if (!T) + return; + + // Nuke the binding. + + ValueState StImpl = *St; + StImpl.CheckerState = RefBFactory.Remove(B, Sym).getRoot(); + St = Eng.getStateManager().getPersistentState(StImpl); + + // Hand of the remaining logic to the parent implementation. + GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, St, TargetLV, Val); +} + // End-of-path. void CFRefCount::EvalEndPath(GRExprEngine& Engine, |