Correctly invalidate reference count state when passing objects by reference in message expressions we don't understand.

llvm-svn: 50541
This commit is contained in:
Ted Kremenek
2008-05-01 21:31:50 +00:00
parent 4f3d7cd12e
commit 8a56b06b5c
2 changed files with 44 additions and 3 deletions

View File

@@ -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,

View File

@@ -203,6 +203,12 @@ RVal ValueStateManager::GetRVal(ValueState* St, LVal LV, QualType T) {
return UnknownVal();
}
case lval::ConcreteIntKind:
// Some clients may call GetRVal with such an option simply because
// they are doing a quick scan through their LVals (potentially to
// invalidate their bindings). Just return Undefined.
return UndefinedVal();
case lval::ArrayOffsetKind:
case lval::FieldOffsetKind: