Added generation of symbolic values for the return values of functions that have

no summaries (useful for false-path pruning).

llvm-svn: 48301
This commit is contained in:
Ted Kremenek 2008-03-12 21:06:49 +00:00
parent 86f1d0cd80
commit 626bd2d33e
1 changed files with 26 additions and 12 deletions

View File

@ -507,7 +507,7 @@ public:
// Calls. // Calls.
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst, virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
GRExprEngine& Engine, GRExprEngine& Eng,
GRStmtNodeBuilder<ValueState>& Builder, GRStmtNodeBuilder<ValueState>& Builder,
CallExpr* CE, LVal L, CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred); ExplodedNode<ValueState>* Pred);
@ -531,12 +531,12 @@ void CFRefCount::BindingsPrinter::PrintCheckerState(std::ostream& Out,
} }
void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst, void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
GRExprEngine& Engine, GRExprEngine& Eng,
GRStmtNodeBuilder<ValueState>& Builder, GRStmtNodeBuilder<ValueState>& Builder,
CallExpr* CE, LVal L, CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred) { ExplodedNode<ValueState>* Pred) {
ValueStateManager& StateMgr = Engine.getStateManager(); ValueStateManager& StateMgr = Eng.getStateManager();
// FIXME: Support calls to things other than lval::FuncVal. At the very // FIXME: Support calls to things other than lval::FuncVal. At the very
// least we should stop tracking ref-state for ref-counted objects passed // least we should stop tracking ref-state for ref-counted objects passed
@ -548,7 +548,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
lval::FuncVal FV = cast<lval::FuncVal>(L); lval::FuncVal FV = cast<lval::FuncVal>(L);
FunctionDecl* FD = FV.getDecl(); FunctionDecl* FD = FV.getDecl();
CFRefSummary* Summ = Summaries.getSummary(FD, Engine.getContext()); CFRefSummary* Summ = Summaries.getSummary(FD, Eng.getContext());
// Get the state. // Get the state.
@ -583,6 +583,20 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
} }
St = StateMgr.getPersistentState(StVals); St = StateMgr.getPersistentState(StVals);
// Make up a symbol for the return value of this function.
if (CE->getType() != Eng.getContext().VoidTy) {
unsigned Count = Builder.getCurrentBlockCount();
SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
RVal X = CE->getType()->isPointerType()
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
}
Builder.Nodify(Dst, CE, Pred, St); Builder.Nodify(Dst, CE, Pred, St);
return; return;
} }
@ -644,13 +658,13 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
unsigned idx = RE.getValue(); unsigned idx = RE.getValue();
assert (idx < CE->getNumArgs()); assert (idx < CE->getNumArgs());
RVal V = StateMgr.GetRVal(St, CE->getArg(idx)); RVal V = StateMgr.GetRVal(St, CE->getArg(idx));
St = StateMgr.SetRVal(St, CE, V, Engine.getCFG().isBlkExpr(CE), false); St = StateMgr.SetRVal(St, CE, V, Eng.getCFG().isBlkExpr(CE), false);
break; break;
} }
case RetEffect::OwnedSymbol: { case RetEffect::OwnedSymbol: {
unsigned Count = Builder.getCurrentBlockCount(); unsigned Count = Builder.getCurrentBlockCount();
SymbolID Sym = Engine.getSymbolManager().getCallRetValSymbol(CE, Count); SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
ValueState StImpl = *St; ValueState StImpl = *St;
RefBindings B = GetRefBindings(StImpl); RefBindings B = GetRefBindings(StImpl);
@ -658,14 +672,14 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl), St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
CE, lval::SymbolVal(Sym), CE, lval::SymbolVal(Sym),
Engine.getCFG().isBlkExpr(CE), false); Eng.getCFG().isBlkExpr(CE), false);
break; break;
} }
case RetEffect::NotOwnedSymbol: { case RetEffect::NotOwnedSymbol: {
unsigned Count = Builder.getCurrentBlockCount(); unsigned Count = Builder.getCurrentBlockCount();
SymbolID Sym = Engine.getSymbolManager().getCallRetValSymbol(CE, Count); SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
ValueState StImpl = *St; ValueState StImpl = *St;
RefBindings B = GetRefBindings(StImpl); RefBindings B = GetRefBindings(StImpl);
@ -673,7 +687,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl), St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
CE, lval::SymbolVal(Sym), CE, lval::SymbolVal(Sym),
Engine.getCFG().isBlkExpr(CE), false); Eng.getCFG().isBlkExpr(CE), false);
break; break;
} }
@ -771,11 +785,11 @@ namespace clang {
// FIXME: Refactor some day so this becomes a single function invocation. // FIXME: Refactor some day so this becomes a single function invocation.
GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx); GRCoreEngine<GRExprEngine> Eng(cfg, FD, Ctx);
GRExprEngine* CS = &Engine.getCheckerState(); GRExprEngine* CS = &Eng.getCheckerState();
CFRefCount TF; CFRefCount TF;
CS->setTransferFunctions(TF); CS->setTransferFunctions(TF);
Engine.ExecuteWorkList(20000); Eng.ExecuteWorkList(20000);
} }