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 | 8a56b06b5c8583a9e53ee361f2709013f7616b98 (patch) | |
tree | 5d0585cfacc8f38d2a6d86c93f48495889890c64 /clang/lib/Analysis/CFRefCount.cpp | |
parent | 4f3d7cd12e1a6771d48daa5844762e69614684d7 (diff) | |
download | bcm5719-llvm-8a56b06b5c8583a9e53ee361f2709013f7616b98.tar.gz bcm5719-llvm-8a56b06b5c8583a9e53ee361f2709013f7616b98.zip |
Correctly invalidate reference count state when passing objects by reference in message expressions we don't understand.
llvm-svn: 50541
Diffstat (limited to 'clang/lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | clang/lib/Analysis/CFRefCount.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 54009040132..98287921d3b 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/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, |