diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRCoreEngine.h | 16 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 65 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ValueState.h | 1 | ||||
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 21 |
4 files changed, 52 insertions, 51 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index d4074af5a9..bef2e2c0b6 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -151,12 +151,14 @@ public: } ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State, - ExplodedNodeImpl* Pred); + ExplodedNodeImpl* Pred, + bool isLoad = false); - inline ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State) { + inline ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State, + bool isLoad = false) { ExplodedNodeImpl* N = getLastNode(); assert (N && "Predecessor of new node is infeasible."); - return generateNodeImpl(S, State, N); + return generateNodeImpl(S, State, N, isLoad); } Stmt* getStmt() const { return B[Idx]; } @@ -201,14 +203,14 @@ public: return static_cast<NodeTy*>(NB.getLastNode()); } - NodeTy* generateNode(Stmt* S, StateTy* St, NodeTy* Pred) { + NodeTy* generateNode(Stmt* S, StateTy* St, NodeTy* Pred, bool isLoad = false){ HasGeneratedNode = true; - return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred)); + return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, isLoad)); } - NodeTy* generateNode(Stmt* S, StateTy* St) { + NodeTy* generateNode(Stmt* S, StateTy* St, bool isLoad = false) { HasGeneratedNode = true; - return static_cast<NodeTy*>(NB.generateNodeImpl(S, St)); + return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, isLoad)); } GRBlockCounter getBlockCounter() const { diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index de8807a201..7005263033 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -425,10 +425,6 @@ protected: return StateMgr.GetRVal(St, LV, T); } - RVal GetLVal(ValueState* St, Expr* Ex) { - return StateMgr.GetLVal(St, Ex); - } - inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) { return NonLVal::MakeVal(BasicVals, X, Ex->getType()); } @@ -474,11 +470,7 @@ protected: assert (Builder && "GRStmtNodeBuilder not present."); return Builder->MakeNode(Dst, S, Pred, St); } - - /// HandleUndefinedStore - Create the necessary sink node to represent - /// a store to an "undefined" LVal. - void HandleUndefinedStore(Stmt* S, NodeTy* Pred); - + /// Visit - Transfer function logic for all statements. Dispatches to /// other functions that handle specific kinds of statements. void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst); @@ -520,7 +512,8 @@ protected: void VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst); /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs. - void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst); + void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst, + bool asLval); /// VisitDeclStmt - Transfer function logic for DeclStmts. void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst); @@ -528,12 +521,6 @@ protected: void VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D, NodeTy* Pred, NodeSet& Dst); - void VisitDeref(UnaryOperator* U, NodeTy* Pred, NodeSet& Dst, - bool GetLVal = false); - - void VisitDeref(Expr* Ex, RVal V, ValueState* St, NodeTy* Pred, NodeSet& Dst, - bool GetLVal); - /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, NodeTy* Pred, NodeSet& Dst); @@ -543,10 +530,6 @@ protected: /// VisitMemberExpr - Transfer function for member expressions. void VisitMemberExpr(MemberExpr* M, NodeTy* Pred, NodeSet& Dst, bool asLVal); - void VisitMemberExprField(MemberExpr* M, Expr* Base, NodeTy* Pred, - NodeSet& Dst, bool asLVal); - - /// VisitObjCMessageExpr - Transfer function for ObjC message expressions. void VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred, NodeSet& Dst); @@ -564,15 +547,12 @@ protected: /// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex, NodeTy* Pred, NodeSet& Dst); - - // VisitSizeOfExpr - Transfer function for sizeof(expr). - void VisitSizeOfExpr(UnaryOperator* U, NodeTy* Pred, NodeSet& Dst); - + /// VisitUnaryOperator - Transfer function logic for unary operators. - void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst); - - - + void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst, + bool asLVal); + + bool CheckDivideZero(Expr* Ex, ValueState* St, NodeTy* Pred, RVal Denom); RVal EvalCast(RVal X, QualType CastT) { if (X.isUnknownOrUndef()) @@ -584,8 +564,6 @@ protected: return TF->EvalCast(*this, cast<NonLVal>(X), CastT); } - - RVal EvalMinus(UnaryOperator* U, RVal X) { return X.isValid() ? TF->EvalMinus(*this, U, cast<NonLVal>(X)) : X; } @@ -603,27 +581,27 @@ protected: } RVal EvalBinOp(BinaryOperator::Opcode Op, RVal L, RVal R) { - + if (L.isUndef() || R.isUndef()) return UndefinedVal(); - + if (L.isUnknown() || R.isUnknown()) return UnknownVal(); - + if (isa<LVal>(L)) { if (isa<LVal>(R)) return TF->EvalBinOp(*this, Op, cast<LVal>(L), cast<LVal>(R)); else return TF->EvalBinOp(*this, Op, cast<LVal>(L), cast<NonLVal>(R)); } - + if (isa<LVal>(R)) { // Support pointer arithmetic where the increment/decrement operand // is on the left and the pointer on the right. - + assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); - // Commute the operands. + // Commute the operands. return TF->EvalBinOp(*this, Op, cast<LVal>(R), cast<NonLVal>(L)); } else @@ -631,11 +609,11 @@ protected: } void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) { - assert (Builder && "GRStmtNodeBuilder must be defined."); + assert (Builder && "GRStmtNodeBuilder must be defined."); TF->EvalCall(Dst, *this, *Builder, CE, L, Pred); } - void EvalObjCMessageExpr(NodeSet& Dst, ObjCMessageExpr* ME, NodeTy* Pred) { + void EvalObjCMessageExpr(NodeSet& Dst, ObjCMessageExpr* ME, NodeTy* Pred) { assert (Builder && "GRStmtNodeBuilder must be defined."); TF->EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred); } @@ -643,7 +621,16 @@ protected: void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St, RVal TargetLV, RVal Val); - void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred); + // FIXME: The "CheckOnly" option exists only because Array and Field + // loads aren't fully implemented. Eventually this option will go away. + + void EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred, + ValueState* St, RVal location, bool CheckOnly = false); + + ValueState* EvalLocation(Expr* Ex, NodeTy* Pred, + ValueState* St, RVal location, bool isLoad = false); + + void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred); ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken); }; diff --git a/include/clang/Analysis/PathSensitive/ValueState.h b/include/clang/Analysis/PathSensitive/ValueState.h index 5e287b23b0..a4133085a8 100644 --- a/include/clang/Analysis/PathSensitive/ValueState.h +++ b/include/clang/Analysis/PathSensitive/ValueState.h @@ -242,7 +242,6 @@ public: RVal GetRVal(ValueState* St, Expr* E); RVal GetRVal(ValueState* St, LVal LV, QualType T = QualType()); - RVal GetLVal(ValueState* St, Expr* E); RVal GetBlkExprRVal(ValueState* St, Expr* Ex); diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 5fc1fb651b..efd16b416d 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -25,8 +25,9 @@ namespace clang { class ProgramPoint { public: - enum Kind { BlockEntranceKind=0, PostStmtKind=1, BlockExitKind=2, - BlockEdgeSrcKind=3, BlockEdgeDstKind=4, BlockEdgeAuxKind=5 }; + enum Kind { BlockEntranceKind=0, PostStmtKind=1, PostLoadKind=2, + BlockExitKind=3, BlockEdgeSrcKind=4, BlockEdgeDstKind=5, + BlockEdgeAuxKind=6 }; protected: uintptr_t Data; @@ -100,13 +101,25 @@ public: class PostStmt : public ProgramPoint { +protected: + PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {} public: PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} - + Stmt* getStmt() const { return (Stmt*) getRawPtr(); } static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostStmtKind; + unsigned k = Location->getKind(); + return k == PostStmtKind || k == PostLoadKind; + } +}; + +class PostLoad : public PostStmt { +public: + PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {} + + static bool classof(const ProgramPoint* Location) { + return Location->getKind() == PostLoadKind; } }; |