diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-05-01 21:31:50 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-05-01 21:31:50 +0000 |
commit | 9040c65860932fc8eded28e1558394d66d44b4cf (patch) | |
tree | 3240d5bb6d4c937a79e42a3b7d09c2238e056e2d /lib/Analysis/CFRefCount.cpp | |
parent | 73c083c27c00228fce8c9f139dc7cda5754b0837 (diff) |
Correctly invalidate reference count state when passing objects by reference in message expressions we don't understand.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 5400904013..98287921d3 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -294,7 +294,7 @@ CFRefSummary* CFRefSummaryManager::getCFSummary(FunctionDecl* FD, if (strcmp(FName, "Release") == 0) return getUnaryCFSummary(FT, cfrelease); - + if (strcmp(FName, "MakeCollectable") == 0) return getUnaryCFSummary(FT, cfmakecollectable); @@ -962,8 +962,43 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst, ObjCMessageExpr* ME, ExplodedNode<ValueState>* Pred) { - if (EvalObjCMessageExprAux(Dst, Eng, Builder, ME, Pred)) - GRSimpleVals::EvalObjCMessageExpr(Dst, Eng, Builder, ME, Pred); + if (!EvalObjCMessageExprAux(Dst, Eng, Builder, ME, Pred)) + return; + + // The basic transfer function logic for message expressions does nothing. + // We just invalidate all arguments passed in by references. + + ValueStateManager& StateMgr = Eng.getStateManager(); + ValueState* St = Builder.GetState(Pred); + RefBindings B = GetRefBindings(*St); + + for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); + I != E; ++I) { + + RVal V = StateMgr.GetRVal(St, *I); + + if (isa<LVal>(V)) { + + LVal lv = cast<LVal>(V); + + // Did the lval bind to a symbol? + RVal X = StateMgr.GetRVal(St, lv); + + if (isa<lval::SymbolVal>(X)) { + SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol(); + B = Remove(B, Sym); + + // Create a new state with the updated bindings. + ValueState StVals = *St; + SetRefBindings(StVals, B); + St = StateMgr.getPersistentState(StVals); + } + + St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal()); + } + } + + Builder.MakeNode(Dst, ME, Pred, St); } bool CFRefCount::EvalObjCMessageExprAux(ExplodedNodeSet<ValueState>& Dst, |