зеркало из https://github.com/microsoft/clang-1.git
Begin major changes to EvalXXX methods in GRTransferFuncs. Currently some of the methods only return an RVal; we want them to be able to create an arbitrary number of states.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53739 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1f3846e301
Коммит
df7533b5e5
|
@ -609,6 +609,10 @@ protected:
|
|||
return TF->EvalBinOp(*this, Op, cast<NonLVal>(L), cast<NonLVal>(R));
|
||||
}
|
||||
|
||||
void EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* E,
|
||||
BinaryOperator::Opcode Op,
|
||||
NonLVal L, NonLVal R, ExplodedNode<ValueState>* Pred);
|
||||
|
||||
void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) {
|
||||
assert (Builder && "GRStmtNodeBuilder must be defined.");
|
||||
TF->EvalCall(Dst, *this, *Builder, CE, L, Pred);
|
||||
|
|
|
@ -49,7 +49,16 @@ public:
|
|||
// Binary Operators.
|
||||
|
||||
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
|
||||
NonLVal L, NonLVal R) = 0;
|
||||
NonLVal L, NonLVal R) {
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
virtual void EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<ValueState>& Builder,
|
||||
BinaryOperator::Opcode Op, Expr* Ex,
|
||||
NonLVal L, NonLVal R,
|
||||
ExplodedNode<ValueState>* Pred);
|
||||
|
||||
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
|
||||
LVal L, LVal R) = 0;
|
||||
|
|
|
@ -185,6 +185,7 @@ template<> struct GRTrait<ValueState*> {
|
|||
|
||||
|
||||
class ValueStateManager {
|
||||
friend class GRExprEngine;
|
||||
|
||||
private:
|
||||
EnvironmentManager EnvMgr;
|
||||
|
@ -210,6 +211,13 @@ private:
|
|||
/// This vector is persistent because it is reused over and over.
|
||||
StoreManager::DeclRootsTy DRoots;
|
||||
|
||||
/// CurrentStmt - The block-level statement currently being visited. This
|
||||
/// is set by GRExprEngine.
|
||||
Stmt* CurrentStmt;
|
||||
|
||||
/// cfg - The CFG for the analyzed function/method.
|
||||
CFG& cfg;
|
||||
|
||||
private:
|
||||
|
||||
Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
|
||||
|
@ -223,7 +231,7 @@ private:
|
|||
|
||||
public:
|
||||
ValueStateManager(ASTContext& Ctx, StoreManager* stmgr,
|
||||
llvm::BumpPtrAllocator& alloc)
|
||||
llvm::BumpPtrAllocator& alloc, CFG& c)
|
||||
: EnvMgr(alloc),
|
||||
StMgr(stmgr),
|
||||
ISetFactory(alloc),
|
||||
|
@ -231,7 +239,8 @@ public:
|
|||
CEFactory(alloc),
|
||||
BasicVals(Ctx, alloc),
|
||||
SymMgr(alloc),
|
||||
Alloc(alloc) {}
|
||||
Alloc(alloc),
|
||||
cfg(c) {}
|
||||
|
||||
const ValueState* getInitialState();
|
||||
|
||||
|
@ -273,6 +282,20 @@ public:
|
|||
NewSt.Env = NewEnv;
|
||||
return getPersistentState(NewSt);
|
||||
}
|
||||
|
||||
const ValueState* SetRVal(const ValueState* St, Expr* Ex, RVal V) {
|
||||
|
||||
bool isBlkExpr = false;
|
||||
|
||||
if (Ex == CurrentStmt) {
|
||||
isBlkExpr = cfg.isBlkExpr(Ex);
|
||||
|
||||
if (!isBlkExpr)
|
||||
return St;
|
||||
}
|
||||
|
||||
return SetRVal(St, Ex, V, isBlkExpr, true);
|
||||
}
|
||||
|
||||
// Methods that query & manipulate the Store.
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
|
|||
Liveness(L),
|
||||
Builder(NULL),
|
||||
StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
|
||||
G.getAllocator()),
|
||||
G.getAllocator(), G.getCFG()),
|
||||
BasicVals(StateMgr.getBasicValueFactory()),
|
||||
TF(NULL), // FIXME
|
||||
SymMgr(StateMgr.getSymbolManager()),
|
||||
|
@ -242,7 +242,10 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
|
|||
|
||||
Builder = &builder;
|
||||
EntryNode = builder.getLastNode();
|
||||
|
||||
// FIXME: Consolidate.
|
||||
CurrentStmt = S;
|
||||
StateMgr.CurrentStmt = S;
|
||||
|
||||
// Set up our simple checks.
|
||||
if (BatchAuditor)
|
||||
|
@ -296,7 +299,11 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
|
|||
// NULL out these variables to cleanup.
|
||||
CleanedState = NULL;
|
||||
EntryNode = NULL;
|
||||
CurrentStmt = NULL;
|
||||
|
||||
// FIXME: Consolidate.
|
||||
StateMgr.CurrentStmt = 0;
|
||||
CurrentStmt = 0;
|
||||
|
||||
Builder = NULL;
|
||||
}
|
||||
|
||||
|
@ -1802,8 +1809,13 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
}
|
||||
else {
|
||||
nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
|
||||
#if 0
|
||||
RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
|
||||
St = SetRVal(St, U, Result);
|
||||
#else
|
||||
EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLVal>(V), X, *I);
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -2225,6 +2237,31 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Transfer-function Helpers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* Ex,
|
||||
BinaryOperator::Opcode Op,
|
||||
NonLVal L, NonLVal R,
|
||||
ExplodedNode<ValueState>* Pred) {
|
||||
|
||||
if (!R.isValid()) {
|
||||
MakeNode(Dst, Ex, Pred, SetRVal(GetState(Pred), Ex, R));
|
||||
return;
|
||||
}
|
||||
|
||||
assert (Builder && "GRStmtNodeBuilder must be defined.");
|
||||
unsigned size = Dst.size();
|
||||
SaveOr OldHasGen(Builder->HasGeneratedNode);
|
||||
|
||||
TF->EvalBinOpNN(Dst, *this, *Builder, Op, Ex, L, R, Pred);
|
||||
|
||||
if (!Builder->BuildSinks && Dst.size() == size &&
|
||||
!Builder->HasGeneratedNode)
|
||||
MakeNode(Dst, Ex, Pred, GetState(Pred));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// "Assume" logic.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -37,3 +37,18 @@ void GRTransferFuncs::EvalStore(ExplodedNodeSet<ValueState>& Dst,
|
|||
Builder.MakeNode(Dst, E, Pred,
|
||||
Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));
|
||||
}
|
||||
|
||||
void GRTransferFuncs::EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<ValueState>& Builder,
|
||||
BinaryOperator::Opcode Op,
|
||||
Expr* Ex,
|
||||
NonLVal L, NonLVal R,
|
||||
ExplodedNode<ValueState>* Pred) {
|
||||
|
||||
ValueStateManager& StateMgr = Engine.getStateManager();
|
||||
const ValueState* St = Builder.GetState(Pred);
|
||||
|
||||
RVal Result = EvalBinOp(Engine, Op, L, R);
|
||||
Builder.MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, Result));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче