зеркало из https://github.com/microsoft/clang-1.git
This is the first step to build a better evaluation model for GRExprEngine. A
new VisitLValue method is added to replace the old VisitLVal. The semantics model becomes more explicit to separate rvalue evaluation from lvalue evaluation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57627 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5db4b3f3ed
Коммит
6d69b5d822
|
@ -73,6 +73,9 @@ public:
|
|||
}
|
||||
|
||||
RVal GetRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
|
||||
RVal GetRVal(const Expr* Ex, BasicValueFactory& BasicVals) const {
|
||||
return GetRVal(const_cast<Expr*>(Ex), BasicVals);
|
||||
}
|
||||
RVal GetBlkExprRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
|
||||
|
||||
/// Profile - Profile the contents of an Environment object for use
|
||||
|
|
|
@ -439,6 +439,11 @@ protected:
|
|||
RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
|
||||
return StateMgr.GetRVal(St, LV, T);
|
||||
}
|
||||
|
||||
// Get the lvalue of an expression.
|
||||
RVal GetLValue(const GRState* St, const Expr* Ex) {
|
||||
return StateMgr.GetLValue(St, Ex);
|
||||
}
|
||||
|
||||
inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
|
||||
return NonLVal::MakeVal(getBasicVals(), X, Ex->getType());
|
||||
|
@ -466,16 +471,14 @@ protected:
|
|||
/// other functions that handle specific kinds of statements.
|
||||
void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
|
||||
|
||||
/// VisitLVal - Similar to Visit, but the specified expression is assummed
|
||||
/// to be evaluated under the context where it evaluates to an LVal. For
|
||||
/// example, if Ex is a DeclRefExpr, under Visit Ex would evaluate to the
|
||||
/// value bound to Ex in the symbolic state, while under VisitLVal it would
|
||||
/// evaluate to an LVal representing the location of the referred Decl.
|
||||
void VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst);
|
||||
/// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is
|
||||
/// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
|
||||
/// storage location. Note that not all kinds of expressions has lvalue.
|
||||
void VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst);
|
||||
|
||||
/// VisitArraySubscriptExpr - Transfer function for array accesses.
|
||||
void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, NodeTy* Pred,
|
||||
NodeSet& Dst, bool asLVal);
|
||||
NodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitAsmStmt - Transfer function logic for inline asm.
|
||||
void VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst);
|
||||
|
@ -500,11 +503,11 @@ protected:
|
|||
NodeSet& Dst);
|
||||
|
||||
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
|
||||
void VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst);
|
||||
void VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst);
|
||||
|
||||
/// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
|
||||
void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst,
|
||||
bool asLval);
|
||||
bool asLValue);
|
||||
|
||||
/// VisitDeclStmt - Transfer function logic for DeclStmts.
|
||||
void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
|
||||
|
@ -516,7 +519,7 @@ protected:
|
|||
void VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
|
||||
|
||||
/// VisitMemberExpr - Transfer function for member expressions.
|
||||
void VisitMemberExpr(MemberExpr* M, NodeTy* Pred, NodeSet& Dst, bool asLVal);
|
||||
void VisitMemberExpr(MemberExpr* M, NodeTy* Pred, NodeSet& Dst,bool asLValue);
|
||||
|
||||
/// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
|
||||
void VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred, NodeSet& Dst);
|
||||
|
@ -538,7 +541,7 @@ protected:
|
|||
|
||||
/// VisitUnaryOperator - Transfer function logic for unary operators.
|
||||
void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst,
|
||||
bool asLVal);
|
||||
bool asLValue);
|
||||
|
||||
bool CheckDivideZero(Expr* Ex, const GRState* St, NodeTy* Pred,
|
||||
RVal Denom);
|
||||
|
|
|
@ -234,7 +234,7 @@ class GRStateManager {
|
|||
|
||||
private:
|
||||
EnvironmentManager EnvMgr;
|
||||
llvm::OwningPtr<StoreManager> StMgr;
|
||||
llvm::OwningPtr<StoreManager> StoreMgr;
|
||||
llvm::OwningPtr<ConstraintManager> ConstraintMgr;
|
||||
GRState::IntSetTy::Factory ISetFactory;
|
||||
|
||||
|
@ -303,7 +303,7 @@ public:
|
|||
Alloc(alloc),
|
||||
cfg(c),
|
||||
Liveness(L) {
|
||||
StMgr.reset((*CreateStoreManager)(*this));
|
||||
StoreMgr.reset((*CreateStoreManager)(*this));
|
||||
ConstraintMgr.reset((*CreateConstraintManager)(*this));
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ public:
|
|||
SymbolManager& getSymbolManager() { return SymMgr; }
|
||||
LiveVariables& getLiveVariables() { return Liveness; }
|
||||
llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
|
||||
MemRegionManager& getRegionManager() { return StMgr->getRegionManager(); }
|
||||
MemRegionManager& getRegionManager() { return StoreMgr->getRegionManager(); }
|
||||
|
||||
typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
|
||||
|
||||
|
@ -342,14 +342,25 @@ public:
|
|||
}
|
||||
|
||||
LVal getLVal(const VarDecl* D) {
|
||||
return StMgr->getLVal(D);
|
||||
return StoreMgr->getLVal(D);
|
||||
}
|
||||
|
||||
|
||||
// Get the lvalue of expression.
|
||||
RVal GetLValue(const GRState* St, const Expr* Ex) {
|
||||
// Forward to store manager. The lvalue of an expression is determined by
|
||||
// the store manager.
|
||||
return StoreMgr->getLValue(St, Ex);
|
||||
}
|
||||
|
||||
// Methods that query & manipulate the Environment.
|
||||
|
||||
RVal GetRVal(const GRState* St, Expr* Ex) {
|
||||
return St->getEnvironment().GetRVal(Ex, BasicVals);
|
||||
}
|
||||
|
||||
RVal GetRVal(const GRState* St, const Expr* Ex) {
|
||||
return St->getEnvironment().GetRVal(Ex, BasicVals);
|
||||
}
|
||||
|
||||
RVal GetBlkExprRVal(const GRState* St, Expr* Ex) {
|
||||
return St->getEnvironment().GetBlkExprRVal(Ex, BasicVals);
|
||||
|
@ -397,22 +408,22 @@ public:
|
|||
// Methods that query & manipulate the Store.
|
||||
|
||||
void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) {
|
||||
StMgr->iterBindings(state->getStore(), F);
|
||||
StoreMgr->iterBindings(state->getStore(), F);
|
||||
}
|
||||
|
||||
|
||||
RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
|
||||
return StMgr->GetRVal(St->getStore(), LV, T);
|
||||
return StoreMgr->GetRVal(St->getStore(), LV, T);
|
||||
}
|
||||
|
||||
void SetRVal(GRState& St, LVal LV, RVal V) {
|
||||
St.St = StMgr->SetRVal(St.St, LV, V);
|
||||
St.St = StoreMgr->SetRVal(St.St, LV, V);
|
||||
}
|
||||
|
||||
const GRState* SetRVal(const GRState* St, LVal LV, RVal V);
|
||||
|
||||
void Unbind(GRState& St, LVal LV) {
|
||||
St.St = StMgr->Remove(St.St, LV);
|
||||
St.St = StoreMgr->Remove(St.St, LV);
|
||||
}
|
||||
|
||||
const GRState* Unbind(const GRState* St, LVal LV);
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
namespace clang {
|
||||
|
||||
typedef const void* Store;
|
||||
|
||||
|
||||
class GRState;
|
||||
class GRStateManager;
|
||||
class LiveVariables;
|
||||
class Stmt;
|
||||
class Expr;
|
||||
class MemRegion;
|
||||
class MemRegionManager;
|
||||
|
||||
|
@ -43,6 +45,10 @@ public:
|
|||
virtual Store getInitialStore() = 0;
|
||||
virtual MemRegionManager& getRegionManager() = 0;
|
||||
virtual LVal getLVal(const VarDecl* VD) = 0;
|
||||
|
||||
// Get the lvalue of an expression.
|
||||
virtual RVal getLValue(const GRState* St, const Expr* Ex) = 0;
|
||||
|
||||
virtual Store
|
||||
RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
|
||||
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
|
||||
|
|
|
@ -42,9 +42,12 @@ public:
|
|||
|
||||
virtual MemRegionManager& getRegionManager() { return MRMgr; }
|
||||
|
||||
// FIXME: Investigate what is using this. This method should be removed.
|
||||
virtual LVal getLVal(const VarDecl* VD) {
|
||||
return lval::MemRegionVal(MRMgr.getVarRegion(VD));
|
||||
}
|
||||
|
||||
virtual RVal getLValue(const GRState* St, const Expr* Ex);
|
||||
|
||||
virtual Store
|
||||
RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
|
||||
|
@ -73,6 +76,35 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
|
|||
return new BasicStoreManager(StMgr);
|
||||
}
|
||||
|
||||
// FIXME: replace ArrayOffset and FieldOffset with some region value.
|
||||
RVal BasicStoreManager::getLValue(const GRState* St, const Expr* Ex) {
|
||||
if (const DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(Ex)) {
|
||||
const VarDecl* VD = cast<VarDecl>(DRE->getDecl());
|
||||
QualType T = VD->getType();
|
||||
|
||||
// Array and struct variable have no lvalue.
|
||||
assert(!T->isArrayType());
|
||||
|
||||
return lval::MemRegionVal(MRMgr.getVarRegion(VD));
|
||||
|
||||
} else if (const ArraySubscriptExpr* A = dyn_cast<ArraySubscriptExpr>(Ex)) {
|
||||
const Expr* Base = A->getBase()->IgnoreParens();
|
||||
const Expr* Idx = A->getIdx()->IgnoreParens();
|
||||
RVal BaseV = StateMgr.GetRVal(St, Base);
|
||||
RVal IdxV = StateMgr.GetRVal(St, Idx);
|
||||
return lval::ArrayOffset::Make(StateMgr.getBasicVals(), BaseV, IdxV);
|
||||
|
||||
} else if (const MemberExpr* M = dyn_cast<MemberExpr>(Ex)) {
|
||||
Expr* Base = M->getBase()->IgnoreParens();
|
||||
RVal BaseV = StateMgr.GetRVal(St, Base);
|
||||
return lval::FieldOffset::Make(StateMgr.getBasicVals(), BaseV,
|
||||
M->getMemberDecl());
|
||||
} else {
|
||||
Ex->dump();
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
|
||||
|
||||
if (isa<UnknownVal>(LV))
|
||||
|
|
|
@ -395,7 +395,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
|
||||
void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
|
||||
|
||||
Ex = Ex->IgnoreParens();
|
||||
|
||||
|
@ -406,8 +406,8 @@ void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
|
|||
|
||||
switch (Ex->getStmtClass()) {
|
||||
default:
|
||||
Visit(Ex, Pred, Dst);
|
||||
return;
|
||||
Ex->dump();
|
||||
assert(0 && "Other kinds of expressions do not have lvalue.");
|
||||
|
||||
case Stmt::ArraySubscriptExprClass:
|
||||
VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
|
||||
|
@ -788,59 +788,79 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
|
|||
// Transfer functions: Loads and stores.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst,
|
||||
bool asLVal) {
|
||||
void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
|
||||
bool asLValue) {
|
||||
|
||||
const GRState* St = GetState(Pred);
|
||||
RVal X = RVal::MakeVal(getStateManager(), D);
|
||||
|
||||
if (asLVal)
|
||||
MakeNode(Dst, D, Pred, SetRVal(St, D, cast<LVal>(X)));
|
||||
else {
|
||||
RVal V = isa<lval::MemRegionVal>(X) ? GetRVal(St, cast<LVal>(X)) : X;
|
||||
MakeNode(Dst, D, Pred, SetRVal(St, D, V));
|
||||
|
||||
const ValueDecl* D = Ex->getDecl();
|
||||
|
||||
if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
|
||||
|
||||
QualType T = VD->getType();
|
||||
if (T->isArrayType()) {
|
||||
assert(!asLValue && "Array variable has no lvalue.");
|
||||
|
||||
// C++ standard says array value should be implicitly converted to pointer
|
||||
// in some cases. We don't have such context information right now. We
|
||||
// use a MemRegionVal to represent this. May be changed in the future.
|
||||
|
||||
RVal V = lval::MemRegionVal(StateMgr.getRegion(VD));
|
||||
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
|
||||
return;
|
||||
}
|
||||
|
||||
RVal V = GetLValue(St, Ex);
|
||||
if (asLValue)
|
||||
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
|
||||
else
|
||||
EvalLoad(Dst, Ex, Pred, St, V);
|
||||
return;
|
||||
|
||||
} else if (const EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
|
||||
assert(!asLValue && "EnumConstantDecl does not have lvalue.");
|
||||
|
||||
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
|
||||
RVal V = nonlval::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
|
||||
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
|
||||
return;
|
||||
|
||||
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
|
||||
assert(!asLValue && "FunctionDecl does not have lvalue.");
|
||||
|
||||
RVal V = lval::FuncVal(FD);
|
||||
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
|
||||
return;
|
||||
}
|
||||
|
||||
assert (false &&
|
||||
"ValueDecl support for this ValueDecl not implemented.");
|
||||
}
|
||||
|
||||
/// VisitArraySubscriptExpr - Transfer function for array accesses
|
||||
void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
|
||||
NodeSet& Dst, bool asLVal) {
|
||||
NodeSet& Dst, bool asLValue) {
|
||||
|
||||
Expr* Base = A->getBase()->IgnoreParens();
|
||||
Expr* Idx = A->getIdx()->IgnoreParens();
|
||||
|
||||
// Always visit the base as an LVal expression. This computes the
|
||||
// abstract address of the base object.
|
||||
NodeSet Tmp;
|
||||
|
||||
if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
|
||||
Visit(Base, Pred, Tmp);
|
||||
else
|
||||
VisitLVal(Base, Pred, Tmp);
|
||||
|
||||
// Get Base's rvalue, which should be an LocVal.
|
||||
Visit(Base, Pred, Tmp);
|
||||
|
||||
for (NodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
|
||||
|
||||
// Evaluate the index.
|
||||
|
||||
NodeSet Tmp2;
|
||||
Visit(Idx, *I1, Tmp2);
|
||||
|
||||
for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) {
|
||||
|
||||
const GRState* St = GetState(*I2);
|
||||
RVal BaseV = GetRVal(St, Base);
|
||||
RVal IdxV = GetRVal(St, Idx);
|
||||
|
||||
// If IdxV is 0, return just BaseV.
|
||||
|
||||
bool useBase = false;
|
||||
|
||||
if (nonlval::ConcreteInt* IdxInt = dyn_cast<nonlval::ConcreteInt>(&IdxV))
|
||||
useBase = IdxInt->getValue() == 0;
|
||||
|
||||
RVal V = useBase ? BaseV : lval::ArrayOffset::Make(getBasicVals(), BaseV,IdxV);
|
||||
RVal V = GetLValue(St, A);
|
||||
|
||||
if (asLVal)
|
||||
if (asLValue)
|
||||
MakeNode(Dst, A, *I2, SetRVal(St, A, V));
|
||||
else
|
||||
EvalLoad(Dst, A, *I2, St, V);
|
||||
|
@ -850,65 +870,22 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
|
|||
|
||||
/// VisitMemberExpr - Transfer function for member expressions.
|
||||
void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
|
||||
NodeSet& Dst, bool asLVal) {
|
||||
NodeSet& Dst, bool asLValue) {
|
||||
|
||||
Expr* Base = M->getBase()->IgnoreParens();
|
||||
|
||||
// Always visit the base as an LVal expression. This computes the
|
||||
// abstract address of the base object.
|
||||
NodeSet Tmp;
|
||||
|
||||
if (asLVal) {
|
||||
|
||||
if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
|
||||
Visit(Base, Pred, Tmp);
|
||||
else
|
||||
VisitLVal(Base, Pred, Tmp);
|
||||
|
||||
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
||||
const GRState* St = GetState(*I);
|
||||
RVal BaseV = GetRVal(St, Base);
|
||||
|
||||
RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
|
||||
M->getMemberDecl());
|
||||
|
||||
MakeNode(Dst, M, *I, SetRVal(St, M, V));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Evaluate the base. Can be an LVal or NonLVal (depends on whether
|
||||
// or not isArrow() is true).
|
||||
// Get Base expr's rvalue.
|
||||
Visit(Base, Pred, Tmp);
|
||||
|
||||
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
||||
|
||||
for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
|
||||
const GRState* St = GetState(*I);
|
||||
RVal BaseV = GetRVal(St, Base);
|
||||
|
||||
if (LVal::IsLValType(Base->getType())) {
|
||||
|
||||
assert (M->isArrow());
|
||||
|
||||
RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
|
||||
M->getMemberDecl());
|
||||
|
||||
EvalLoad(Dst, M, *I, St, V);
|
||||
}
|
||||
else {
|
||||
|
||||
assert (!M->isArrow());
|
||||
|
||||
if (BaseV.isUnknownOrUndef()) {
|
||||
MakeNode(Dst, M, *I, SetRVal(St, M, BaseV));
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Implement nonlval objects representing struct temporaries.
|
||||
assert (isa<NonLVal>(BaseV));
|
||||
MakeNode(Dst, M, *I, SetRVal(St, M, UnknownVal()));
|
||||
}
|
||||
RVal L = GetLValue(St, M);
|
||||
if (asLValue)
|
||||
MakeNode(Dst, M, *I, SetRVal(St, M, L));
|
||||
else
|
||||
EvalLoad(Dst, M, *I, St, L);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1080,7 +1057,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
|
|||
NodeSet DstTmp;
|
||||
Expr* Callee = CE->getCallee()->IgnoreParens();
|
||||
|
||||
VisitLVal(Callee, Pred, DstTmp);
|
||||
Visit(Callee, Pred, DstTmp);
|
||||
|
||||
// Finally, evaluate the function call.
|
||||
for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
|
||||
|
@ -1412,12 +1389,11 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
|
||||
|
||||
NodeSet S1;
|
||||
QualType T = CastE->getType();
|
||||
|
||||
if (T->isReferenceType())
|
||||
VisitLVal(Ex, Pred, S1);
|
||||
VisitLValue(Ex, Pred, S1);
|
||||
else
|
||||
Visit(Ex, Pred, S1);
|
||||
|
||||
|
@ -1562,7 +1538,7 @@ void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
|
|||
|
||||
|
||||
void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
||||
NodeSet& Dst, bool asLVal) {
|
||||
NodeSet& Dst, bool asLValue) {
|
||||
|
||||
switch (U->getOpcode()) {
|
||||
|
||||
|
@ -1580,7 +1556,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
const GRState* St = GetState(*I);
|
||||
RVal location = GetRVal(St, Ex);
|
||||
|
||||
if (asLVal)
|
||||
if (asLValue)
|
||||
MakeNode(Dst, U, *I, SetRVal(St, U, location));
|
||||
else
|
||||
EvalLoad(Dst, U, *I, St, location);
|
||||
|
@ -1642,7 +1618,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
Dst.Add(Pred);
|
||||
return;
|
||||
|
||||
case UnaryOperator::Plus: assert (!asLVal); // FALL-THROUGH.
|
||||
case UnaryOperator::Plus: assert (!asLValue); // FALL-THROUGH.
|
||||
case UnaryOperator::Extension: {
|
||||
|
||||
// Unary "+" is a no-op, similar to a parentheses. We still have places
|
||||
|
@ -1664,10 +1640,10 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
|
||||
case UnaryOperator::AddrOf: {
|
||||
|
||||
assert (!asLVal);
|
||||
assert(!asLValue);
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
NodeSet Tmp;
|
||||
VisitLVal(Ex, Pred, Tmp);
|
||||
VisitLValue(Ex, Pred, Tmp);
|
||||
|
||||
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
||||
const GRState* St = GetState(*I);
|
||||
|
@ -1683,7 +1659,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
case UnaryOperator::Minus:
|
||||
case UnaryOperator::Not: {
|
||||
|
||||
assert (!asLVal);
|
||||
assert (!asLValue);
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
NodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
@ -1774,7 +1750,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
|
|||
assert (U->isIncrementDecrementOp());
|
||||
NodeSet Tmp;
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
VisitLVal(Ex, Pred, Tmp);
|
||||
VisitLValue(Ex, Pred, Tmp);
|
||||
|
||||
for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
|
||||
|
||||
|
@ -1824,7 +1800,7 @@ void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
|
|||
}
|
||||
|
||||
NodeSet Tmp;
|
||||
VisitLVal(*I, Pred, Tmp);
|
||||
VisitLValue(*I, Pred, Tmp);
|
||||
|
||||
++I;
|
||||
|
||||
|
@ -1994,7 +1970,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
|||
Expr* RHS = B->getRHS()->IgnoreParens();
|
||||
|
||||
if (B->isAssignmentOp())
|
||||
VisitLVal(LHS, Pred, Tmp1);
|
||||
VisitLValue(LHS, Pred, Tmp1);
|
||||
else
|
||||
Visit(LHS, Pred, Tmp1);
|
||||
|
||||
|
@ -2033,7 +2009,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
|||
// Simulate the effects of a "store": bind the value of the RHS
|
||||
// to the L-Value represented by the LHS.
|
||||
|
||||
EvalStore(Dst, B, LHS, *I2, SetRVal(St, B, RightV), LeftV, RightV);
|
||||
EvalStore(Dst, B, LHS, *I2, SetRVal(St, B, RightV), LeftV, RightV);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
|
|||
|
||||
// Clean up the store.
|
||||
DSymbols.clear();
|
||||
NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness,
|
||||
NewSt.St = StoreMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness,
|
||||
RegionRoots, LSymbols, DSymbols);
|
||||
|
||||
return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewSt),
|
||||
|
@ -63,7 +63,7 @@ const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
|
|||
RVal V) {
|
||||
|
||||
Store OldStore = St->getStore();
|
||||
Store NewStore = StMgr->SetRVal(OldStore, LV, V);
|
||||
Store NewStore = StoreMgr->SetRVal(OldStore, LV, V);
|
||||
|
||||
if (NewStore == OldStore)
|
||||
return St;
|
||||
|
@ -79,10 +79,10 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
|
|||
Store NewStore;
|
||||
|
||||
if (Ex)
|
||||
NewStore = StMgr->AddDecl(OldStore, VD, Ex,
|
||||
NewStore = StoreMgr->AddDecl(OldStore, VD, Ex,
|
||||
GetRVal(St, Ex), Count);
|
||||
else
|
||||
NewStore = StMgr->AddDecl(OldStore, VD, Ex);
|
||||
NewStore = StoreMgr->AddDecl(OldStore, VD, Ex);
|
||||
|
||||
if (NewStore == OldStore)
|
||||
return St;
|
||||
|
@ -94,7 +94,7 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
|
|||
|
||||
const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
|
||||
Store OldStore = St->getStore();
|
||||
Store NewStore = StMgr->Remove(OldStore, LV);
|
||||
Store NewStore = StoreMgr->Remove(OldStore, LV);
|
||||
|
||||
if (NewStore == OldStore)
|
||||
return St;
|
||||
|
@ -107,7 +107,7 @@ const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
|
|||
const GRState* GRStateManager::getInitialState() {
|
||||
|
||||
GRState StateImpl(EnvMgr.getInitialEnvironment(),
|
||||
StMgr->getInitialStore(),
|
||||
StoreMgr->getInitialStore(),
|
||||
GDMFactory.GetEmptyMap());
|
||||
|
||||
return getPersistentState(StateImpl);
|
||||
|
@ -196,7 +196,7 @@ void GRStateRef::printStdErr() const {
|
|||
void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
|
||||
GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
|
||||
GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();
|
||||
St->print(Out, *Mgr->StMgr, *Mgr->ConstraintMgr, beg, end, nl, sep);
|
||||
St->print(Out, *Mgr->StoreMgr, *Mgr->ConstraintMgr, beg, end, nl, sep);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -270,6 +270,7 @@ LVal LVal::MakeVal(StringLiteral* S) {
|
|||
// Utility methods for constructing RVals (both NonLVals and LVals).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Remove this method?
|
||||
RVal RVal::MakeVal(GRStateManager& SMgr, DeclRefExpr* E) {
|
||||
|
||||
ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
|
||||
|
|
Загрузка…
Ссылка в новой задаче