forked from OSchip/llvm-project
Constify all references to Stmt* and CFGBlock* in libChecker.
llvm-svn: 108811
This commit is contained in:
parent
09a95d7448
commit
edb77fe8b4
|
@ -109,16 +109,16 @@ public:
|
|||
const void *tag = 0)
|
||||
: ProgramPoint(B, BlockEntranceKind, L, tag) {}
|
||||
|
||||
CFGBlock* getBlock() const {
|
||||
return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
|
||||
const CFGBlock* getBlock() const {
|
||||
return reinterpret_cast<const CFGBlock*>(getData1());
|
||||
}
|
||||
|
||||
CFGElement getFirstElement() const {
|
||||
const CFGElement getFirstElement() const {
|
||||
const CFGBlock* B = getBlock();
|
||||
return B->empty() ? CFGElement() : B->front();
|
||||
}
|
||||
|
||||
Stmt *getFirstStmt() const {
|
||||
const Stmt *getFirstStmt() const {
|
||||
return getFirstElement().getStmt();
|
||||
}
|
||||
|
||||
|
@ -132,16 +132,16 @@ public:
|
|||
BlockExit(const CFGBlock* B, const LocationContext *L)
|
||||
: ProgramPoint(B, BlockExitKind, L) {}
|
||||
|
||||
CFGBlock* getBlock() const {
|
||||
return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
|
||||
const CFGBlock* getBlock() const {
|
||||
return reinterpret_cast<const CFGBlock*>(getData1());
|
||||
}
|
||||
|
||||
Stmt* getLastStmt() const {
|
||||
const Stmt* getLastStmt() const {
|
||||
const CFGBlock* B = getBlock();
|
||||
return B->empty() ? CFGElement() : B->back();
|
||||
}
|
||||
|
||||
Stmt* getTerminator() const {
|
||||
const Stmt* getTerminator() const {
|
||||
return getBlock()->getTerminator();
|
||||
}
|
||||
|
||||
|
@ -300,12 +300,12 @@ public:
|
|||
BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L)
|
||||
: ProgramPoint(B1, B2, BlockEdgeKind, L) {}
|
||||
|
||||
CFGBlock* getSrc() const {
|
||||
return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
|
||||
const CFGBlock* getSrc() const {
|
||||
return static_cast<const CFGBlock*>(getData1());
|
||||
}
|
||||
|
||||
CFGBlock* getDst() const {
|
||||
return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
|
||||
const CFGBlock* getDst() const {
|
||||
return static_cast<const CFGBlock*>(getData2());
|
||||
}
|
||||
|
||||
static bool classof(const ProgramPoint* Location) {
|
||||
|
|
|
@ -269,7 +269,7 @@ public:
|
|||
|
||||
virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
|
||||
GRExprEngine &Eng,
|
||||
Stmt *Condition, void *tag) {}
|
||||
const Stmt *Condition, void *tag) {}
|
||||
|
||||
virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
|
||||
return false;
|
||||
|
|
|
@ -67,11 +67,11 @@ class GRCoreEngine {
|
|||
|
||||
void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
|
||||
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
|
||||
void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
|
||||
void HandlePostStmt(const PostStmt& S, CFGBlock* B,
|
||||
void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred);
|
||||
void HandlePostStmt(const PostStmt& S, const CFGBlock* B,
|
||||
unsigned StmtIdx, ExplodedNode *Pred);
|
||||
|
||||
void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
|
||||
void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B,
|
||||
ExplodedNode* Pred);
|
||||
void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
|
||||
unsigned Index, ExplodedNode *Pred);
|
||||
|
@ -84,13 +84,13 @@ class GRCoreEngine {
|
|||
|
||||
void ProcessEndPath(GREndPathNodeBuilder& Builder);
|
||||
|
||||
void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
|
||||
void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& Builder);
|
||||
|
||||
bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
|
||||
bool ProcessBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred,
|
||||
GRBlockCounter BC);
|
||||
|
||||
|
||||
void ProcessBranch(Stmt* Condition, Stmt* Terminator,
|
||||
void ProcessBranch(const Stmt* Condition, const Stmt* Terminator,
|
||||
GRBranchNodeBuilder& Builder);
|
||||
|
||||
|
||||
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
class GRStmtNodeBuilder {
|
||||
GRCoreEngine& Eng;
|
||||
CFGBlock& B;
|
||||
const CFGBlock& B;
|
||||
const unsigned Idx;
|
||||
ExplodedNode* Pred;
|
||||
GRStateManager& Mgr;
|
||||
|
@ -163,7 +163,7 @@ public:
|
|||
void GenerateAutoTransition(ExplodedNode* N);
|
||||
|
||||
public:
|
||||
GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N,
|
||||
GRStmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N,
|
||||
GRCoreEngine* e, GRStateManager &mgr);
|
||||
|
||||
~GRStmtNodeBuilder();
|
||||
|
@ -222,11 +222,11 @@ public:
|
|||
|
||||
/// getStmt - Return the current block-level expression associated with
|
||||
/// this builder.
|
||||
Stmt* getStmt() const { return B[Idx]; }
|
||||
const Stmt* getStmt() const { return B[Idx]; }
|
||||
|
||||
/// getBlock - Return the CFGBlock associated with the block-level expression
|
||||
/// of this builder.
|
||||
CFGBlock* getBlock() const { return &B; }
|
||||
const CFGBlock* getBlock() const { return &B; }
|
||||
|
||||
unsigned getIndex() const { return Idx; }
|
||||
|
||||
|
@ -259,9 +259,9 @@ public:
|
|||
|
||||
class GRBranchNodeBuilder {
|
||||
GRCoreEngine& Eng;
|
||||
CFGBlock* Src;
|
||||
CFGBlock* DstT;
|
||||
CFGBlock* DstF;
|
||||
const CFGBlock* Src;
|
||||
const CFGBlock* DstT;
|
||||
const CFGBlock* DstF;
|
||||
ExplodedNode* Pred;
|
||||
|
||||
typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
|
||||
|
@ -273,8 +273,8 @@ class GRBranchNodeBuilder {
|
|||
bool InFeasibleFalse;
|
||||
|
||||
public:
|
||||
GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
|
||||
ExplodedNode* pred, GRCoreEngine* e)
|
||||
GRBranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT,
|
||||
const CFGBlock* dstF, ExplodedNode* pred, GRCoreEngine* e)
|
||||
: Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
|
||||
GeneratedTrue(false), GeneratedFalse(false),
|
||||
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
|
||||
|
@ -289,7 +289,7 @@ public:
|
|||
|
||||
ExplodedNode* generateNode(const GRState* State, bool branch);
|
||||
|
||||
CFGBlock* getTargetBlock(bool branch) const {
|
||||
const CFGBlock* getTargetBlock(bool branch) const {
|
||||
return branch ? DstT : DstF;
|
||||
}
|
||||
|
||||
|
@ -311,31 +311,31 @@ public:
|
|||
|
||||
class GRIndirectGotoNodeBuilder {
|
||||
GRCoreEngine& Eng;
|
||||
CFGBlock* Src;
|
||||
CFGBlock& DispatchBlock;
|
||||
Expr* E;
|
||||
const CFGBlock* Src;
|
||||
const CFGBlock& DispatchBlock;
|
||||
const Expr* E;
|
||||
ExplodedNode* Pred;
|
||||
|
||||
public:
|
||||
GRIndirectGotoNodeBuilder(ExplodedNode* pred, CFGBlock* src, Expr* e,
|
||||
CFGBlock* dispatch, GRCoreEngine* eng)
|
||||
: Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
|
||||
GRIndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
|
||||
const Expr* e, const CFGBlock* dispatch, GRCoreEngine* eng)
|
||||
: Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
|
||||
|
||||
class iterator {
|
||||
CFGBlock::succ_iterator I;
|
||||
CFGBlock::const_succ_iterator I;
|
||||
|
||||
friend class GRIndirectGotoNodeBuilder;
|
||||
iterator(CFGBlock::succ_iterator i) : I(i) {}
|
||||
iterator(CFGBlock::const_succ_iterator i) : I(i) {}
|
||||
public:
|
||||
|
||||
iterator& operator++() { ++I; return *this; }
|
||||
bool operator!=(const iterator& X) const { return I != X.I; }
|
||||
|
||||
LabelStmt* getLabel() const {
|
||||
const LabelStmt* getLabel() const {
|
||||
return llvm::cast<LabelStmt>((*I)->getLabel());
|
||||
}
|
||||
|
||||
CFGBlock* getBlock() const {
|
||||
const CFGBlock* getBlock() const {
|
||||
return *I;
|
||||
}
|
||||
};
|
||||
|
@ -346,37 +346,37 @@ public:
|
|||
ExplodedNode* generateNode(const iterator& I, const GRState* State,
|
||||
bool isSink = false);
|
||||
|
||||
Expr* getTarget() const { return E; }
|
||||
const Expr* getTarget() const { return E; }
|
||||
|
||||
const GRState* getState() const { return Pred->State; }
|
||||
};
|
||||
|
||||
class GRSwitchNodeBuilder {
|
||||
GRCoreEngine& Eng;
|
||||
CFGBlock* Src;
|
||||
Expr* Condition;
|
||||
const CFGBlock* Src;
|
||||
const Expr* Condition;
|
||||
ExplodedNode* Pred;
|
||||
|
||||
public:
|
||||
GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src,
|
||||
Expr* condition, GRCoreEngine* eng)
|
||||
GRSwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
|
||||
const Expr* condition, GRCoreEngine* eng)
|
||||
: Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
|
||||
|
||||
class iterator {
|
||||
CFGBlock::succ_reverse_iterator I;
|
||||
CFGBlock::const_succ_reverse_iterator I;
|
||||
|
||||
friend class GRSwitchNodeBuilder;
|
||||
iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
|
||||
iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
|
||||
|
||||
public:
|
||||
iterator& operator++() { ++I; return *this; }
|
||||
bool operator!=(const iterator& X) const { return I != X.I; }
|
||||
|
||||
CaseStmt* getCase() const {
|
||||
const CaseStmt* getCase() const {
|
||||
return llvm::cast<CaseStmt>((*I)->getLabel());
|
||||
}
|
||||
|
||||
CFGBlock* getBlock() const {
|
||||
const CFGBlock* getBlock() const {
|
||||
return *I;
|
||||
}
|
||||
};
|
||||
|
@ -389,21 +389,21 @@ public:
|
|||
ExplodedNode* generateDefaultCaseNode(const GRState* State,
|
||||
bool isSink = false);
|
||||
|
||||
Expr* getCondition() const { return Condition; }
|
||||
const Expr* getCondition() const { return Condition; }
|
||||
|
||||
const GRState* getState() const { return Pred->State; }
|
||||
};
|
||||
|
||||
class GREndPathNodeBuilder {
|
||||
GRCoreEngine &Eng;
|
||||
CFGBlock& B;
|
||||
const CFGBlock& B;
|
||||
ExplodedNode* Pred;
|
||||
|
||||
public:
|
||||
bool HasGeneratedNode;
|
||||
|
||||
public:
|
||||
GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
|
||||
GREndPathNodeBuilder(const CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
|
||||
: Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
|
||||
|
||||
~GREndPathNodeBuilder();
|
||||
|
@ -427,7 +427,7 @@ public:
|
|||
|
||||
void GenerateCallExitNode(const GRState *state);
|
||||
|
||||
CFGBlock* getBlock() const { return &B; }
|
||||
const CFGBlock* getBlock() const { return &B; }
|
||||
|
||||
const GRState* getState() const {
|
||||
return getPredecessor()->getState();
|
||||
|
|
|
@ -64,7 +64,7 @@ class GRExprEngine : public GRSubEngine {
|
|||
const GRState* CleanedState;
|
||||
|
||||
/// CurrentStmt - The current block-level statement.
|
||||
Stmt* CurrentStmt;
|
||||
const Stmt* CurrentStmt;
|
||||
|
||||
// Obj-C Class Identifiers.
|
||||
IdentifierInfo* NSExceptionII;
|
||||
|
@ -101,10 +101,10 @@ class GRExprEngine : public GRSubEngine {
|
|||
|
||||
class CallExprWLItem {
|
||||
public:
|
||||
CallExpr::arg_iterator I;
|
||||
CallExpr::const_arg_iterator I;
|
||||
ExplodedNode *N;
|
||||
|
||||
CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
|
||||
CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
|
||||
: I(i), N(n) {}
|
||||
};
|
||||
|
||||
|
@ -166,17 +166,18 @@ public:
|
|||
|
||||
/// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
|
||||
/// nodes by processing the 'effects' of a block-level statement.
|
||||
void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder);
|
||||
void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder);
|
||||
|
||||
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
|
||||
/// a CFGBlock. This method returns true if the analysis should continue
|
||||
/// exploring the given path, and false otherwise.
|
||||
bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
|
||||
bool ProcessBlockEntrance(const CFGBlock* B, const ExplodedNode *Pred,
|
||||
GRBlockCounter BC);
|
||||
|
||||
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor
|
||||
/// nodes by processing the 'effects' of a branch condition.
|
||||
void ProcessBranch(Stmt* Condition, Stmt* Term, GRBranchNodeBuilder& builder);
|
||||
void ProcessBranch(const Stmt* Condition, const Stmt* Term,
|
||||
GRBranchNodeBuilder& builder);
|
||||
|
||||
/// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
|
||||
/// nodes by processing the 'effects' of a computed goto jump.
|
||||
|
@ -201,7 +202,7 @@ public:
|
|||
|
||||
/// EvalAssume - Callback function invoked by the ConstraintManager when
|
||||
/// making assumptions about state values.
|
||||
const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
|
||||
const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption);
|
||||
|
||||
GRStateManager& getStateManager() { return StateMgr; }
|
||||
const GRStateManager& getStateManager() const { return StateMgr; }
|
||||
|
@ -240,7 +241,7 @@ public:
|
|||
|
||||
/// CheckerVisit - Dispatcher for performing checker-specific logic
|
||||
/// at specific statements.
|
||||
void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||
void CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||
bool isPrevisit);
|
||||
|
||||
bool CheckerEvalCall(const CallExpr *CE,
|
||||
|
@ -259,118 +260,124 @@ public:
|
|||
|
||||
/// Visit - Transfer function logic for all statements. Dispatches to
|
||||
/// other functions that handle specific kinds of statements.
|
||||
void Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& 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, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitArraySubscriptExpr - Transfer function for array accesses.
|
||||
void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, ExplodedNode* Pred,
|
||||
void VisitArraySubscriptExpr(const ArraySubscriptExpr* Ex, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitAsmStmt - Transfer function logic for inline asm.
|
||||
void VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
void VisitAsmStmtHelperOutputs(AsmStmt* A,
|
||||
AsmStmt::outputs_iterator I,
|
||||
AsmStmt::outputs_iterator E,
|
||||
void VisitAsmStmtHelperOutputs(const AsmStmt* A,
|
||||
AsmStmt::const_outputs_iterator I,
|
||||
AsmStmt::const_outputs_iterator E,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
void VisitAsmStmtHelperInputs(AsmStmt* A,
|
||||
AsmStmt::inputs_iterator I,
|
||||
AsmStmt::inputs_iterator E,
|
||||
void VisitAsmStmtHelperInputs(const AsmStmt* A,
|
||||
AsmStmt::const_inputs_iterator I,
|
||||
AsmStmt::const_inputs_iterator E,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitBlockExpr - Transfer function logic for BlockExprs.
|
||||
void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
|
||||
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
/// VisitBinaryOperator - Transfer function logic for binary operators.
|
||||
void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred,
|
||||
void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
|
||||
/// VisitCall - Transfer function for function calls.
|
||||
void VisitCall(CallExpr* CE, ExplodedNode* Pred,
|
||||
CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
|
||||
void VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
||||
CallExpr::const_arg_iterator AI,
|
||||
CallExpr::const_arg_iterator AE,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
|
||||
void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
|
||||
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst, bool asLValue);
|
||||
|
||||
/// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
|
||||
void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst,
|
||||
bool asLValue);
|
||||
|
||||
/// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
|
||||
void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
|
||||
void VisitDeclRefExpr(const DeclRefExpr* DR, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
|
||||
void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
|
||||
void VisitBlockDeclRefExpr(const BlockDeclRefExpr* DR, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst,
|
||||
bool asLValue);
|
||||
|
||||
/// VisitDeclStmt - Transfer function logic for DeclStmts.
|
||||
void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
|
||||
void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitCondInit - Transfer function for handling the initialization
|
||||
/// of a condition variable in an IfStmt, SwitchStmt, etc.
|
||||
void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
|
||||
void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
||||
void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitLogicalExpr - Transfer function logic for '&&', '||'
|
||||
void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
|
||||
void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitMemberExpr - Transfer function for member expressions.
|
||||
void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
|
||||
bool asLValue);
|
||||
void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
|
||||
void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
|
||||
void VisitObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitObjCForCollectionStmt - Transfer function logic for
|
||||
/// ObjCForCollectionStmt.
|
||||
void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
|
||||
void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, SVal ElementV);
|
||||
|
||||
/// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
|
||||
void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
|
||||
void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
/// VisitReturnStmt - Transfer function logic for return statements.
|
||||
void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitOffsetOfExpr - Transfer function for offsetof.
|
||||
void VisitOffsetOfExpr(OffsetOfExpr* Ex, ExplodedNode* Pred,
|
||||
void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
|
||||
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
|
||||
void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitUnaryOperator - Transfer function logic for unary operators.
|
||||
void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred,
|
||||
void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue);
|
||||
|
||||
void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
|
||||
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet & Dst);
|
||||
|
||||
void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
|
||||
|
@ -380,17 +387,17 @@ public:
|
|||
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
void VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
|
||||
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
/// Create a C++ temporary object for an rvalue.
|
||||
void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
|
||||
void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
||||
/// Synthesize CXXThisRegion.
|
||||
|
@ -398,14 +405,15 @@ public:
|
|||
const StackFrameContext *SFC);
|
||||
|
||||
/// Evaluate arguments with a work list algorithm.
|
||||
void EvalArguments(ExprIterator AI, ExprIterator AE,
|
||||
void EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
const FunctionProtoType *FnType,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst);
|
||||
|
||||
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
|
||||
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
|
||||
/// with those assumptions.
|
||||
void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, Expr *Ex);
|
||||
void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
|
||||
const Expr *Ex);
|
||||
|
||||
SVal EvalMinus(SVal X) {
|
||||
return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
|
||||
|
@ -433,13 +441,13 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME,
|
||||
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred, const GRState *state) {
|
||||
assert (Builder && "GRStmtNodeBuilder must be defined.");
|
||||
getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
|
||||
}
|
||||
|
||||
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
|
||||
const GRState* MarkBranch(const GRState* St, const Stmt* Terminator,
|
||||
bool branchTaken);
|
||||
|
||||
/// EvalBind - Handle the semantics of binding a value to a specific location.
|
||||
|
|
|
@ -43,17 +43,17 @@ public:
|
|||
|
||||
/// Called by GRCoreEngine. Used to generate new successor
|
||||
/// nodes by processing the 'effects' of a block-level statement.
|
||||
virtual void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder) = 0;
|
||||
virtual void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder) = 0;
|
||||
|
||||
/// Called by GRCoreEngine when start processing
|
||||
/// a CFGBlock. This method returns true if the analysis should continue
|
||||
/// exploring the given path, and false otherwise.
|
||||
virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
|
||||
virtual bool ProcessBlockEntrance(const CFGBlock* B, const ExplodedNode *Pred,
|
||||
GRBlockCounter BC) = 0;
|
||||
|
||||
/// Called by GRCoreEngine. Used to generate successor
|
||||
/// nodes by processing the 'effects' of a branch condition.
|
||||
virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
|
||||
virtual void ProcessBranch(const Stmt* Condition, const Stmt* Term,
|
||||
GRBranchNodeBuilder& builder) = 0;
|
||||
|
||||
/// Called by GRCoreEngine. Used to generate successor
|
||||
|
|
|
@ -42,13 +42,13 @@ public:
|
|||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
const CallExpr* CE, SVal L,
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred,
|
||||
const GRState *state) {}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public:
|
|||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ReturnStmt* S,
|
||||
const ReturnStmt* S,
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
// Assumptions.
|
||||
|
|
|
@ -27,12 +27,12 @@ class ExplodedNodeImpl;
|
|||
class GRWorkListUnit {
|
||||
ExplodedNode* Node;
|
||||
GRBlockCounter Counter;
|
||||
CFGBlock* Block;
|
||||
const CFGBlock* Block;
|
||||
unsigned BlockIdx; // This is the index of the next statement.
|
||||
|
||||
public:
|
||||
GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
|
||||
CFGBlock* B, unsigned idx)
|
||||
const CFGBlock* B, unsigned idx)
|
||||
: Node(N),
|
||||
Counter(C),
|
||||
Block(B),
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
ExplodedNode* getNode() const { return Node; }
|
||||
GRBlockCounter getBlockCounter() const { return Counter; }
|
||||
CFGBlock* getBlock() const { return Block; }
|
||||
const CFGBlock* getBlock() const { return Block; }
|
||||
unsigned getIndex() const { return BlockIdx; }
|
||||
};
|
||||
|
||||
|
@ -58,8 +58,8 @@ public:
|
|||
|
||||
virtual void Enqueue(const GRWorkListUnit& U) = 0;
|
||||
|
||||
void Enqueue(ExplodedNode* N, CFGBlock& B, unsigned idx) {
|
||||
Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
|
||||
void Enqueue(ExplodedNode* N, const CFGBlock* B, unsigned idx) {
|
||||
Enqueue(GRWorkListUnit(N, CurrentCounter, B, idx));
|
||||
}
|
||||
|
||||
void Enqueue(ExplodedNode* N) {
|
||||
|
|
|
@ -45,15 +45,14 @@ public:
|
|||
enum { BaseBits = 2, BaseMask = 0x3 };
|
||||
|
||||
protected:
|
||||
void* Data;
|
||||
const void* Data;
|
||||
unsigned Kind;
|
||||
|
||||
protected:
|
||||
SVal(const void* d, bool isLoc, unsigned ValKind)
|
||||
: Data(const_cast<void*>(d)),
|
||||
Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
|
||||
: Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
|
||||
|
||||
explicit SVal(BaseKind k, void* D = NULL)
|
||||
explicit SVal(BaseKind k, const void* D = NULL)
|
||||
: Data(D), Kind(k) {}
|
||||
|
||||
public:
|
||||
|
@ -69,7 +68,7 @@ public:
|
|||
|
||||
inline void Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
ID.AddInteger((unsigned) getRawKind());
|
||||
ID.AddPointer(reinterpret_cast<void*>(Data));
|
||||
ID.AddPointer(Data);
|
||||
}
|
||||
|
||||
inline bool operator==(const SVal& R) const {
|
||||
|
@ -163,13 +162,13 @@ public:
|
|||
class UndefinedVal : public SVal {
|
||||
public:
|
||||
UndefinedVal() : SVal(UndefinedKind) {}
|
||||
UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
|
||||
UndefinedVal(const void* D) : SVal(UndefinedKind, D) {}
|
||||
|
||||
static inline bool classof(const SVal* V) {
|
||||
return V->getBaseKind() == UndefinedKind;
|
||||
}
|
||||
|
||||
void* getData() const { return Data; }
|
||||
const void* getData() const { return Data; }
|
||||
};
|
||||
|
||||
class DefinedOrUnknownSVal : public SVal {
|
||||
|
@ -287,7 +286,7 @@ public:
|
|||
: NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
|
||||
|
||||
const SymExpr *getSymbolicExpression() const {
|
||||
return reinterpret_cast<SymExpr*>(Data);
|
||||
return reinterpret_cast<const SymExpr*>(Data);
|
||||
}
|
||||
|
||||
static inline bool classof(const SVal* V) {
|
||||
|
@ -305,7 +304,7 @@ public:
|
|||
ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
|
||||
|
||||
const llvm::APSInt& getValue() const {
|
||||
return *static_cast<llvm::APSInt*>(Data);
|
||||
return *static_cast<const llvm::APSInt*>(Data);
|
||||
}
|
||||
|
||||
// Transfer functions for binary/unary operations on ConcreteInts.
|
||||
|
@ -368,7 +367,7 @@ class CompoundVal : public NonLoc {
|
|||
|
||||
public:
|
||||
const CompoundValData* getValue() const {
|
||||
return static_cast<CompoundValData*>(Data);
|
||||
return static_cast<const CompoundValData*>(Data);
|
||||
}
|
||||
|
||||
typedef llvm::ImmutableList<SVal>::iterator iterator;
|
||||
|
@ -419,8 +418,8 @@ class GotoLabel : public Loc {
|
|||
public:
|
||||
GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
|
||||
|
||||
LabelStmt* getLabel() const {
|
||||
return static_cast<LabelStmt*>(Data);
|
||||
const LabelStmt* getLabel() const {
|
||||
return static_cast<const LabelStmt*>(Data);
|
||||
}
|
||||
|
||||
static inline bool classof(const SVal* V) {
|
||||
|
@ -439,7 +438,7 @@ public:
|
|||
MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
|
||||
|
||||
const MemRegion* getRegion() const {
|
||||
return static_cast<MemRegion*>(Data);
|
||||
return static_cast<const MemRegion*>(Data);
|
||||
}
|
||||
|
||||
const MemRegion* StripCasts() const;
|
||||
|
@ -473,7 +472,7 @@ public:
|
|||
ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
|
||||
|
||||
const llvm::APSInt& getValue() const {
|
||||
return *static_cast<llvm::APSInt*>(Data);
|
||||
return *static_cast<const llvm::APSInt*>(Data);
|
||||
}
|
||||
|
||||
// Transfer functions for binary/unary operations on ConcreteInts.
|
||||
|
|
|
@ -541,9 +541,9 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
ProgramPoint P = N->getLocation();
|
||||
|
||||
if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
|
||||
CFGBlock* Src = BE->getSrc();
|
||||
CFGBlock* Dst = BE->getDst();
|
||||
Stmt* T = Src->getTerminator();
|
||||
const CFGBlock* Src = BE->getSrc();
|
||||
const CFGBlock* Dst = BE->getDst();
|
||||
const Stmt* T = Src->getTerminator();
|
||||
|
||||
if (!T)
|
||||
continue;
|
||||
|
@ -577,7 +577,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
|
||||
if (Stmt* S = Dst->getLabel()) {
|
||||
if (const Stmt* S = Dst->getLabel()) {
|
||||
PathDiagnosticLocation End(S, SMgr);
|
||||
|
||||
switch (S->getStmtClass()) {
|
||||
|
@ -593,17 +593,17 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
|
||||
case Stmt::CaseStmtClass: {
|
||||
os << "Control jumps to 'case ";
|
||||
CaseStmt* Case = cast<CaseStmt>(S);
|
||||
Expr* LHS = Case->getLHS()->IgnoreParenCasts();
|
||||
const CaseStmt* Case = cast<CaseStmt>(S);
|
||||
const Expr* LHS = Case->getLHS()->IgnoreParenCasts();
|
||||
|
||||
// Determine if it is an enum.
|
||||
bool GetRawInt = true;
|
||||
|
||||
if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
|
||||
if (const DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
|
||||
// FIXME: Maybe this should be an assertion. Are there cases
|
||||
// were it is not an EnumConstantDecl?
|
||||
EnumConstantDecl* D =
|
||||
dyn_cast<EnumConstantDecl>(DR->getDecl());
|
||||
const EnumConstantDecl* D =
|
||||
dyn_cast<EnumConstantDecl>(DR->getDecl());
|
||||
|
||||
if (D) {
|
||||
GetRawInt = false;
|
||||
|
@ -668,7 +668,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (!PDB.supportsLogicalOpControlFlow())
|
||||
break;
|
||||
|
||||
BinaryOperator *B = cast<BinaryOperator>(T);
|
||||
const BinaryOperator *B = cast<BinaryOperator>(T);
|
||||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
os << "Left side of '";
|
||||
|
|
|
@ -209,7 +209,7 @@ public:
|
|||
ProgramPoint P = N->getLocation();
|
||||
|
||||
if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
|
||||
CFGBlock *BSrc = BE->getSrc();
|
||||
const CFGBlock *BSrc = BE->getSrc();
|
||||
S = BSrc->getTerminatorCondition();
|
||||
}
|
||||
else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
ProgramPoint P = N->getLocation();
|
||||
|
||||
if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
|
||||
CFGBlock *BSrc = BE->getSrc();
|
||||
const CFGBlock *BSrc = BE->getSrc();
|
||||
S = BSrc->getTerminatorCondition();
|
||||
}
|
||||
else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
|
||||
|
|
|
@ -92,11 +92,11 @@ ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
|
|||
namespace {
|
||||
class GenericNodeBuilder {
|
||||
GRStmtNodeBuilder *SNB;
|
||||
Stmt *S;
|
||||
const Stmt *S;
|
||||
const void *tag;
|
||||
GREndPathNodeBuilder *ENB;
|
||||
public:
|
||||
GenericNodeBuilder(GRStmtNodeBuilder &snb, Stmt *s,
|
||||
GenericNodeBuilder(GRStmtNodeBuilder &snb, const Stmt *s,
|
||||
const void *t)
|
||||
: SNB(&snb), S(s), tag(t), ENB(0) {}
|
||||
|
||||
|
@ -1769,7 +1769,7 @@ private:
|
|||
|
||||
void ProcessNonLeakError(ExplodedNodeSet& Dst,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
Expr* NodeExpr, SourceRange ErrorRange,
|
||||
const Expr* NodeExpr, SourceRange ErrorRange,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* St,
|
||||
RefVal::Kind hasErr, SymbolRef Sym);
|
||||
|
@ -1812,31 +1812,31 @@ public:
|
|||
void EvalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
Expr* Ex,
|
||||
const Expr* Ex,
|
||||
InstanceReceiver Receiver,
|
||||
const RetainSummary& Summ,
|
||||
const MemRegion *Callee,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ConstExprIterator arg_beg, ConstExprIterator arg_end,
|
||||
ExplodedNode* Pred, const GRState *state);
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
const CallExpr* CE, SVal L,
|
||||
ExplodedNode* Pred);
|
||||
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred,
|
||||
const GRState *state);
|
||||
|
||||
bool EvalObjCMessageExprAux(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred);
|
||||
|
||||
// Stores.
|
||||
|
@ -1863,7 +1863,7 @@ public:
|
|||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ReturnStmt* S,
|
||||
const ReturnStmt* S,
|
||||
ExplodedNode* Pred);
|
||||
|
||||
// Assumptions.
|
||||
|
@ -2607,11 +2607,12 @@ static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
|
|||
void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
Expr* Ex,
|
||||
const Expr* Ex,
|
||||
InstanceReceiver Receiver,
|
||||
const RetainSummary& Summ,
|
||||
const MemRegion *Callee,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ConstExprIterator arg_beg,
|
||||
ConstExprIterator arg_end,
|
||||
ExplodedNode* Pred, const GRState *state) {
|
||||
|
||||
// Evaluate the effect of the arguments.
|
||||
|
@ -2622,7 +2623,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
|||
|
||||
llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
|
||||
|
||||
for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
|
||||
for (ConstExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
|
||||
SVal V = state->getSValAsScalarOrLoc(*I);
|
||||
SymbolRef Sym = V.getAsLocSymbol();
|
||||
|
||||
|
@ -2862,7 +2863,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
|||
void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
const CallExpr* CE, SVal L,
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
RetainSummary *Summ = 0;
|
||||
|
@ -2887,7 +2888,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
|
|||
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred,
|
||||
const GRState *state) {
|
||||
RetainSummary *Summ =
|
||||
|
@ -2958,10 +2959,10 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
|
|||
void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ReturnStmt* S,
|
||||
const ReturnStmt* S,
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
Expr* RetE = S->getRetValue();
|
||||
const Expr* RetE = S->getRetValue();
|
||||
if (!RetE)
|
||||
return;
|
||||
|
||||
|
@ -3406,7 +3407,7 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
|
|||
ExplodedNode* Pred,
|
||||
const GRState* state,
|
||||
SymbolReaper& SymReaper) {
|
||||
Stmt *S = Builder.getStmt();
|
||||
const Stmt *S = Builder.getStmt();
|
||||
RefBindings B = state->get<RefBindings>();
|
||||
|
||||
// Update counts from autorelease pools
|
||||
|
@ -3456,7 +3457,8 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
|
|||
|
||||
void CFRefCount::ProcessNonLeakError(ExplodedNodeSet& Dst,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
Expr* NodeExpr, SourceRange ErrorRange,
|
||||
const Expr* NodeExpr,
|
||||
SourceRange ErrorRange,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* St,
|
||||
RefVal::Kind hasErr, SymbolRef Sym) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
using namespace clang;
|
||||
|
||||
void GRExprEngine::EvalArguments(ExprIterator AI, ExprIterator AE,
|
||||
void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
const FunctionProtoType *FnType,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
|
||||
llvm::SmallVector<CallExprWLItem, 20> WorkList;
|
||||
|
@ -55,7 +55,7 @@ const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *D,
|
|||
return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC);
|
||||
}
|
||||
|
||||
void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
|
||||
void GRExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
@ -94,9 +94,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
|
|||
// Evaluate other arguments.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
|
||||
EvalArguments(const_cast<CXXConstructExpr*>(E)->arg_begin(),
|
||||
const_cast<CXXConstructExpr*>(E)->arg_end(),
|
||||
FnType, Pred, ArgsEvaluated);
|
||||
EvalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, ArgsEvaluated);
|
||||
// The callee stack frame context used to create the 'this' parameter region.
|
||||
const StackFrameContext *SFC = AMgr.getStackFrame(CD,
|
||||
Pred->getLocationContext(),
|
||||
|
@ -126,9 +124,7 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
|
|||
|
||||
// Evaluate explicit arguments with a worklist.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
EvalArguments(const_cast<CXXMemberCallExpr*>(MCE)->arg_begin(),
|
||||
const_cast<CXXMemberCallExpr*>(MCE)->arg_end(),
|
||||
FnType, Pred, ArgsEvaluated);
|
||||
EvalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, ArgsEvaluated);
|
||||
|
||||
// Evaluate the implicit object argument.
|
||||
ExplodedNodeSet AllArgsEvaluated;
|
||||
|
@ -169,7 +165,7 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
if (CNE->isArray()) {
|
||||
// FIXME: allocating an array has not been handled.
|
||||
|
@ -177,7 +173,7 @@ void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
}
|
||||
|
||||
unsigned Count = Builder->getCurrentBlockCount();
|
||||
DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE,
|
||||
DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE,
|
||||
CNE->getType(), Count);
|
||||
const MemRegion *NewReg = cast<loc::MemRegionVal>(SymVal).getRegion();
|
||||
|
||||
|
@ -220,8 +216,8 @@ void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
void GRExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
|
||||
ExplodedNode *Pred,ExplodedNodeSet &Dst) {
|
||||
// Should do more checking.
|
||||
ExplodedNodeSet ArgEvaluated;
|
||||
Visit(CDE->getArgument(), Pred, ArgEvaluated);
|
||||
|
@ -232,7 +228,7 @@ void GRExprEngine::VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
// Get the this object region from StoreManager.
|
||||
const MemRegion *R =
|
||||
|
|
|
@ -126,13 +126,14 @@ void GRCoreEngine::ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder) {
|
|||
SubEngine.ProcessStmt(E, Builder);
|
||||
}
|
||||
|
||||
bool GRCoreEngine::ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
|
||||
bool GRCoreEngine::ProcessBlockEntrance(const CFGBlock* Blk,
|
||||
const ExplodedNode *Pred,
|
||||
GRBlockCounter BC) {
|
||||
return SubEngine.ProcessBlockEntrance(Blk, Pred, BC);
|
||||
}
|
||||
|
||||
void GRCoreEngine::ProcessBranch(Stmt* Condition, Stmt* Terminator,
|
||||
GRBranchNodeBuilder& Builder) {
|
||||
void GRCoreEngine::ProcessBranch(const Stmt* Condition, const Stmt* Terminator,
|
||||
GRBranchNodeBuilder& Builder) {
|
||||
SubEngine.ProcessBranch(Condition, Terminator, Builder);
|
||||
}
|
||||
|
||||
|
@ -158,7 +159,7 @@ bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) {
|
|||
if (G->num_roots() == 0) { // Initialize the analysis by constructing
|
||||
// the root if none exists.
|
||||
|
||||
CFGBlock* Entry = &(L->getCFG()->getEntry());
|
||||
const CFGBlock* Entry = &(L->getCFG()->getEntry());
|
||||
|
||||
assert (Entry->empty() &&
|
||||
"Entry block must be empty.");
|
||||
|
@ -167,7 +168,7 @@ bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) {
|
|||
"Entry block must have 1 successor.");
|
||||
|
||||
// Get the solitary successor.
|
||||
CFGBlock* Succ = *(Entry->succ_begin());
|
||||
const CFGBlock* Succ = *(Entry->succ_begin());
|
||||
|
||||
// Construct an edge representing the
|
||||
// starting location in the function.
|
||||
|
@ -239,7 +240,7 @@ void GRCoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
|
|||
|
||||
void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
|
||||
|
||||
CFGBlock* Blk = L.getDst();
|
||||
const CFGBlock* Blk = L.getDst();
|
||||
|
||||
// Check if we are entering the EXIT block.
|
||||
if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
|
||||
|
@ -284,9 +285,9 @@ void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
|
|||
HandleBlockExit(L.getBlock(), Pred);
|
||||
}
|
||||
|
||||
void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
|
||||
void GRCoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode* Pred) {
|
||||
|
||||
if (Stmt* Term = B->getTerminator()) {
|
||||
if (const Stmt* Term = B->getTerminator()) {
|
||||
switch (Term->getStmtClass()) {
|
||||
default:
|
||||
assert(false && "Analysis for this terminator not implemented.");
|
||||
|
@ -372,8 +373,8 @@ void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
|
|||
Pred->State, Pred);
|
||||
}
|
||||
|
||||
void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
|
||||
ExplodedNode* Pred) {
|
||||
void GRCoreEngine::HandleBranch(const Stmt* Cond, const Stmt* Term,
|
||||
const CFGBlock * B, ExplodedNode* Pred) {
|
||||
assert (B->succ_size() == 2);
|
||||
|
||||
GRBranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
|
||||
|
@ -382,7 +383,7 @@ void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
|
|||
ProcessBranch(Cond, Term, Builder);
|
||||
}
|
||||
|
||||
void GRCoreEngine::HandlePostStmt(const PostStmt& L, CFGBlock* B,
|
||||
void GRCoreEngine::HandlePostStmt(const PostStmt& L, const CFGBlock* B,
|
||||
unsigned StmtIdx, ExplodedNode* Pred) {
|
||||
|
||||
assert (!B->empty());
|
||||
|
@ -415,7 +416,7 @@ void GRCoreEngine::GenerateNode(const ProgramPoint& Loc,
|
|||
if (IsNew) WList->Enqueue(Node);
|
||||
}
|
||||
|
||||
GRStmtNodeBuilder::GRStmtNodeBuilder(CFGBlock* b, unsigned idx,
|
||||
GRStmtNodeBuilder::GRStmtNodeBuilder(const CFGBlock* b, unsigned idx,
|
||||
ExplodedNode* N, GRCoreEngine* e,
|
||||
GRStateManager &mgr)
|
||||
: Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr), Auditor(0),
|
||||
|
@ -438,7 +439,7 @@ void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
|
|||
if (isa<CallEnter>(N->getLocation())) {
|
||||
// Still use the index of the CallExpr. It's needed to create the callee
|
||||
// StackFrameContext.
|
||||
Eng.WList->Enqueue(N, B, Idx);
|
||||
Eng.WList->Enqueue(N, &B, Idx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -447,7 +448,7 @@ void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
|
|||
if (Loc == N->getLocation()) {
|
||||
// Note: 'N' should be a fresh node because otherwise it shouldn't be
|
||||
// a member of Deferred.
|
||||
Eng.WList->Enqueue(N, B, Idx+1);
|
||||
Eng.WList->Enqueue(N, &B, Idx+1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -456,7 +457,7 @@ void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
|
|||
Succ->addPredecessor(N, *Eng.G);
|
||||
|
||||
if (IsNew)
|
||||
Eng.WList->Enqueue(Succ, B, Idx+1);
|
||||
Eng.WList->Enqueue(Succ, &B, Idx+1);
|
||||
}
|
||||
|
||||
ExplodedNode* GRStmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
|
||||
|
@ -727,6 +728,6 @@ void GRCallExitNodeBuilder::GenerateNode(const GRState *state) {
|
|||
ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
|
||||
Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
|
||||
if (isNew)
|
||||
Eng.WList->Enqueue(Node, *const_cast<CFGBlock*>(LocCtx->getCallSiteBlock()),
|
||||
Eng.WList->Enqueue(Node, LocCtx->getCallSiteBlock(),
|
||||
LocCtx->getIndex() + 1);
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ public:
|
|||
// Checker worklist routines.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
|
||||
void GRExprEngine::CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst,
|
||||
ExplodedNodeSet &Src, bool isPrevisit) {
|
||||
|
||||
// Determine if we already have a cached 'CheckersOrdered' vector
|
||||
|
@ -522,7 +522,7 @@ void GRExprEngine::ProcessEndWorklist(bool hasWorkRemaining) {
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
|
||||
void GRExprEngine::ProcessStmt(const CFGElement CE,GRStmtNodeBuilder& builder) {
|
||||
CurrentStmt = CE.getStmt();
|
||||
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
|
||||
CurrentStmt->getLocStart(),
|
||||
|
@ -626,7 +626,8 @@ void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
|
|||
Builder = NULL;
|
||||
}
|
||||
|
||||
void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
|
||||
S->getLocStart(),
|
||||
"Error evaluating statement");
|
||||
|
@ -741,7 +742,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
break;
|
||||
|
||||
case Stmt::BinaryOperatorClass: {
|
||||
BinaryOperator* B = cast<BinaryOperator>(S);
|
||||
const BinaryOperator* B = cast<BinaryOperator>(S);
|
||||
|
||||
if (B->isLogicalOp()) {
|
||||
VisitLogicalExpr(B, Pred, Dst);
|
||||
|
@ -767,25 +768,25 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
|
||||
case Stmt::CallExprClass:
|
||||
case Stmt::CXXOperatorCallExprClass: {
|
||||
CallExpr* C = cast<CallExpr>(S);
|
||||
const CallExpr* C = cast<CallExpr>(S);
|
||||
VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case Stmt::CXXMemberCallExprClass: {
|
||||
CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
|
||||
const CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
|
||||
VisitCXXMemberCallExpr(MCE, Pred, Dst);
|
||||
break;
|
||||
}
|
||||
|
||||
case Stmt::CXXNewExprClass: {
|
||||
CXXNewExpr *NE = cast<CXXNewExpr>(S);
|
||||
const CXXNewExpr *NE = cast<CXXNewExpr>(S);
|
||||
VisitCXXNewExpr(NE, Pred, Dst);
|
||||
break;
|
||||
}
|
||||
|
||||
case Stmt::CXXDeleteExprClass: {
|
||||
CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
|
||||
const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
|
||||
VisitCXXDeleteExpr(CDE, Pred, Dst);
|
||||
break;
|
||||
}
|
||||
|
@ -793,7 +794,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
// the CFG do not model them as explicit control-flow.
|
||||
|
||||
case Stmt::ChooseExprClass: { // __builtin_choose_expr
|
||||
ChooseExpr* C = cast<ChooseExpr>(S);
|
||||
const ChooseExpr* C = cast<ChooseExpr>(S);
|
||||
VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
|
||||
break;
|
||||
}
|
||||
|
@ -807,7 +808,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
break;
|
||||
|
||||
case Stmt::ConditionalOperatorClass: { // '?' operator
|
||||
ConditionalOperator* C = cast<ConditionalOperator>(S);
|
||||
const ConditionalOperator* C = cast<ConditionalOperator>(S);
|
||||
VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
|
||||
break;
|
||||
}
|
||||
|
@ -837,7 +838,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
case Stmt::CXXReinterpretCastExprClass:
|
||||
case Stmt::CXXConstCastExprClass:
|
||||
case Stmt::CXXFunctionalCastExprClass: {
|
||||
CastExpr* C = cast<CastExpr>(S);
|
||||
const CastExpr* C = cast<CastExpr>(S);
|
||||
VisitCast(C, C->getSubExpr(), Pred, Dst, false);
|
||||
break;
|
||||
}
|
||||
|
@ -894,7 +895,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
break;
|
||||
|
||||
case Stmt::StmtExprClass: {
|
||||
StmtExpr* SE = cast<StmtExpr>(S);
|
||||
const StmtExpr* SE = cast<StmtExpr>(S);
|
||||
|
||||
if (SE->getSubStmt()->body_empty()) {
|
||||
// Empty statement expression.
|
||||
|
@ -925,7 +926,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
break;
|
||||
|
||||
case Stmt::UnaryOperatorClass: {
|
||||
UnaryOperator *U = cast<UnaryOperator>(S);
|
||||
const UnaryOperator *U = cast<UnaryOperator>(S);
|
||||
if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UnaryOperator::LNot)) {
|
||||
ExplodedNodeSet Tmp;
|
||||
VisitUnaryOperator(U, Pred, Tmp, false);
|
||||
|
@ -944,7 +945,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitLValue(const Expr* Ex, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
|
||||
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
|
||||
|
@ -985,7 +986,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
|||
|
||||
case Stmt::CallExprClass:
|
||||
case Stmt::CXXOperatorCallExprClass: {
|
||||
CallExpr *C = cast<CallExpr>(Ex);
|
||||
const CallExpr *C = cast<CallExpr>(Ex);
|
||||
assert(CalleeReturnsReferenceOrRecord(C));
|
||||
VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);
|
||||
break;
|
||||
|
@ -1001,7 +1002,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
|||
|
||||
case Stmt::ImplicitCastExprClass:
|
||||
case Stmt::CStyleCastExprClass: {
|
||||
CastExpr *C = cast<CastExpr>(Ex);
|
||||
const CastExpr *C = cast<CastExpr>(Ex);
|
||||
QualType T = Ex->getType();
|
||||
VisitCast(C, C->getSubExpr(), Pred, Dst, true);
|
||||
break;
|
||||
|
@ -1016,7 +1017,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
|||
return;
|
||||
|
||||
case Stmt::ObjCMessageExprClass: {
|
||||
ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
|
||||
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
|
||||
assert(ReceiverReturnsReferenceOrRecord(ME));
|
||||
VisitObjCMessageExpr(ME, Pred, Dst, true);
|
||||
return;
|
||||
|
@ -1082,7 +1083,8 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
|||
// Block entrance. (Update counters).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
|
||||
bool GRExprEngine::ProcessBlockEntrance(const CFGBlock* B,
|
||||
const ExplodedNode *Pred,
|
||||
GRBlockCounter BC) {
|
||||
return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(),
|
||||
B->getBlockID()) < AMgr.getMaxLoop();
|
||||
|
@ -1106,8 +1108,8 @@ ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
const GRState* GRExprEngine::MarkBranch(const GRState* state,
|
||||
Stmt* Terminator,
|
||||
bool branchTaken) {
|
||||
const Stmt* Terminator,
|
||||
bool branchTaken) {
|
||||
|
||||
switch (Terminator->getStmtClass()) {
|
||||
default:
|
||||
|
@ -1115,7 +1117,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
|
|||
|
||||
case Stmt::BinaryOperatorClass: { // '&&' and '||'
|
||||
|
||||
BinaryOperator* B = cast<BinaryOperator>(Terminator);
|
||||
const BinaryOperator* B = cast<BinaryOperator>(Terminator);
|
||||
BinaryOperator::Opcode Op = B->getOpcode();
|
||||
|
||||
assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
|
||||
|
@ -1126,21 +1128,21 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
|
|||
// For ||, if we take the false branch, then the value of the whole
|
||||
// expression is that of the RHS expression.
|
||||
|
||||
Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
|
||||
(Op == BinaryOperator::LOr && !branchTaken)
|
||||
? B->getRHS() : B->getLHS();
|
||||
const Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
|
||||
(Op == BinaryOperator::LOr && !branchTaken)
|
||||
? B->getRHS() : B->getLHS();
|
||||
|
||||
return state->BindExpr(B, UndefinedVal(Ex));
|
||||
}
|
||||
|
||||
case Stmt::ConditionalOperatorClass: { // ?:
|
||||
|
||||
ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
|
||||
const ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
|
||||
|
||||
// For ?, if branchTaken == true then the value is either the LHS or
|
||||
// the condition itself. (GNU extension).
|
||||
|
||||
Expr* Ex;
|
||||
const Expr* Ex;
|
||||
|
||||
if (branchTaken)
|
||||
Ex = C->getLHS() ? C->getLHS() : C->getCond();
|
||||
|
@ -1152,9 +1154,9 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
|
|||
|
||||
case Stmt::ChooseExprClass: { // ?:
|
||||
|
||||
ChooseExpr* C = cast<ChooseExpr>(Terminator);
|
||||
const ChooseExpr* C = cast<ChooseExpr>(Terminator);
|
||||
|
||||
Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
|
||||
const Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
|
||||
return state->BindExpr(C, UndefinedVal(Ex));
|
||||
}
|
||||
}
|
||||
|
@ -1166,16 +1168,16 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
|
|||
/// This function returns the SVal bound to Condition->IgnoreCasts if all the
|
||||
// cast(s) did was sign-extend the original value.
|
||||
static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
|
||||
Stmt* Condition, ASTContext& Ctx) {
|
||||
const Stmt* Condition, ASTContext& Ctx) {
|
||||
|
||||
Expr *Ex = dyn_cast<Expr>(Condition);
|
||||
const Expr *Ex = dyn_cast<Expr>(Condition);
|
||||
if (!Ex)
|
||||
return UnknownVal();
|
||||
|
||||
uint64_t bits = 0;
|
||||
bool bitsInit = false;
|
||||
|
||||
while (CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
|
||||
while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
|
||||
QualType T = CE->getType();
|
||||
|
||||
if (!T->isIntegerType())
|
||||
|
@ -1199,7 +1201,7 @@ static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
|
|||
return state->getSVal(Ex);
|
||||
}
|
||||
|
||||
void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
|
||||
void GRExprEngine::ProcessBranch(const Stmt* Condition, const Stmt* Term,
|
||||
GRBranchNodeBuilder& builder) {
|
||||
|
||||
// Check for NULL conditions; e.g. "for(;;)"
|
||||
|
@ -1286,7 +1288,7 @@ void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
|
|||
typedef GRIndirectGotoNodeBuilder::iterator iterator;
|
||||
|
||||
if (isa<loc::GotoLabel>(V)) {
|
||||
LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
|
||||
const LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
|
||||
|
||||
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
|
||||
if (I.getLabel() == L) {
|
||||
|
@ -1315,7 +1317,8 @@ void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
|
|||
}
|
||||
|
||||
|
||||
void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
|
||||
void GRExprEngine::VisitGuardedExpr(const Expr* Ex, const Expr* L,
|
||||
const Expr* R,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
|
||||
assert(Ex == CurrentStmt &&
|
||||
|
@ -1326,7 +1329,7 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
|
|||
|
||||
assert (X.isUndef());
|
||||
|
||||
Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
|
||||
const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
|
||||
assert(SE);
|
||||
X = state->getSVal(SE);
|
||||
|
||||
|
@ -1351,7 +1354,7 @@ void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) {
|
|||
void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
|
||||
typedef GRSwitchNodeBuilder::iterator iterator;
|
||||
const GRState* state = builder.getState();
|
||||
Expr* CondE = builder.getCondition();
|
||||
const Expr* CondE = builder.getCondition();
|
||||
SVal CondV_untested = state->getSVal(CondE);
|
||||
|
||||
if (CondV_untested.isUndef()) {
|
||||
|
@ -1367,7 +1370,7 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
|
|||
bool defaultIsFeasible = false;
|
||||
|
||||
for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
|
||||
CaseStmt* Case = cast<CaseStmt>(I.getCase());
|
||||
const CaseStmt* Case = cast<CaseStmt>(I.getCase());
|
||||
|
||||
// Evaluate the LHS of the case value.
|
||||
Expr::EvalResult V1;
|
||||
|
@ -1383,7 +1386,7 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
|
|||
// Get the RHS of the case, if it exists.
|
||||
Expr::EvalResult V2;
|
||||
|
||||
if (Expr* E = Case->getRHS()) {
|
||||
if (const Expr* E = Case->getRHS()) {
|
||||
b = E->Evaluate(V2, getContext());
|
||||
assert(b && V2.Val.isInt() && !V2.HasSideEffects
|
||||
&& "Case condition must evaluate to an integer constant.");
|
||||
|
@ -1491,7 +1494,7 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
|
|||
// Transfer functions: logical operations ('&&', '||').
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
|
||||
assert(B->getOpcode() == BinaryOperator::LAnd ||
|
||||
|
@ -1545,7 +1548,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
|
|||
// Transfer functions: Loads and stores.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
|
||||
ExplodedNodeSet Tmp;
|
||||
|
@ -1561,18 +1564,18 @@ void GRExprEngine::VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred,
|
|||
CheckerVisit(BE, Dst, Tmp, false);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitDeclRefExpr(const DeclRefExpr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst, bool asLValue) {
|
||||
VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitBlockDeclRefExpr(BlockDeclRefExpr *Ex,
|
||||
void GRExprEngine::VisitBlockDeclRefExpr(const BlockDeclRefExpr *Ex,
|
||||
ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst, bool asLValue) {
|
||||
VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
|
||||
void GRExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
|
||||
ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst, bool asLValue) {
|
||||
|
||||
|
@ -1619,12 +1622,12 @@ void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
|
|||
}
|
||||
|
||||
/// VisitArraySubscriptExpr - Transfer function for array accesses
|
||||
void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
|
||||
void GRExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr* A,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue){
|
||||
|
||||
Expr* Base = A->getBase()->IgnoreParens();
|
||||
Expr* Idx = A->getIdx()->IgnoreParens();
|
||||
const Expr* Base = A->getBase()->IgnoreParens();
|
||||
const Expr* Idx = A->getIdx()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
|
||||
if (Base->getType()->isVectorType()) {
|
||||
|
@ -1659,7 +1662,7 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
|
|||
}
|
||||
|
||||
/// VisitMemberExpr - Transfer function for member expressions.
|
||||
void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue) {
|
||||
|
||||
Expr* Base = M->getBase()->IgnoreParens();
|
||||
|
@ -1912,9 +1915,9 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
|
|||
return false;
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
|
||||
CallExpr::arg_iterator AI,
|
||||
CallExpr::arg_iterator AE,
|
||||
void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
||||
CallExpr::const_arg_iterator AI,
|
||||
CallExpr::const_arg_iterator AE,
|
||||
ExplodedNodeSet& Dst, bool asLValue) {
|
||||
|
||||
// Determine the type of function we're calling (if available).
|
||||
|
@ -1961,7 +1964,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
|
|||
|
||||
// Now process the call itself.
|
||||
ExplodedNodeSet DstTmp;
|
||||
Expr* Callee = CE->getCallee()->IgnoreParens();
|
||||
const Expr* Callee = CE->getCallee()->IgnoreParens();
|
||||
|
||||
for (ExplodedNodeSet::iterator NI=ArgsEvaluated.begin(),
|
||||
NE=ArgsEvaluated.end(); NI != NE; ++NI) {
|
||||
|
@ -2054,7 +2057,7 @@ static std::pair<const void*,const void*> EagerlyAssumeTag
|
|||
= std::pair<const void*,const void*>(&EagerlyAssumeTag,static_cast<void*>(0));
|
||||
|
||||
void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||
Expr *Ex) {
|
||||
const Expr *Ex) {
|
||||
for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
|
||||
ExplodedNode *Pred = *I;
|
||||
|
||||
|
@ -2097,10 +2100,11 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
|||
// Transfer function: Objective-C ivar references.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitObjCIvarRefExpr(const ObjCIvarRefExpr* Ex,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue) {
|
||||
|
||||
Expr* Base = cast<Expr>(Ex->getBase());
|
||||
const Expr* Base = cast<Expr>(Ex->getBase());
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Base, Pred, Tmp);
|
||||
|
||||
|
@ -2120,7 +2124,7 @@ void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred,
|
|||
// Transfer function: Objective-C fast enumeration 'for' statements.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
|
||||
void GRExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
|
||||
// ObjCForCollectionStmts are processed in two places. This method
|
||||
|
@ -2148,11 +2152,11 @@ void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
|
|||
// container is empty. Thus this transfer function will by default
|
||||
// result in state splitting.
|
||||
|
||||
Stmt* elem = S->getElement();
|
||||
const Stmt* elem = S->getElement();
|
||||
SVal ElementV;
|
||||
|
||||
if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
|
||||
VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
|
||||
if (const DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
|
||||
const VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
|
||||
assert (ElemD->getInit() == 0);
|
||||
ElementV = GetState(Pred)->getLValue(ElemD, Pred->getLocationContext());
|
||||
VisitObjCForCollectionStmtAux(S, Pred, Dst, ElementV);
|
||||
|
@ -2168,12 +2172,12 @@ void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
|
||||
void GRExprEngine::VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst,
|
||||
SVal ElementV) {
|
||||
|
||||
// Check if the location we are writing back to is a null pointer.
|
||||
Stmt* elem = S->getElement();
|
||||
const Stmt* elem = S->getElement();
|
||||
ExplodedNodeSet Tmp;
|
||||
EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
|
||||
|
||||
|
@ -2222,23 +2226,24 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
|
|||
namespace {
|
||||
class ObjCMsgWLItem {
|
||||
public:
|
||||
ObjCMessageExpr::arg_iterator I;
|
||||
ObjCMessageExpr::const_arg_iterator I;
|
||||
ExplodedNode *N;
|
||||
|
||||
ObjCMsgWLItem(const ObjCMessageExpr::arg_iterator &i, ExplodedNode *n)
|
||||
ObjCMsgWLItem(const ObjCMessageExpr::const_arg_iterator &i, ExplodedNode *n)
|
||||
: I(i), N(n) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue){
|
||||
|
||||
// Create a worklist to process both the arguments.
|
||||
llvm::SmallVector<ObjCMsgWLItem, 20> WL;
|
||||
|
||||
// But first evaluate the receiver (if any).
|
||||
ObjCMessageExpr::arg_iterator AI = ME->arg_begin(), AE = ME->arg_end();
|
||||
if (Expr *Receiver = ME->getInstanceReceiver()) {
|
||||
ObjCMessageExpr::const_arg_iterator AI = ME->arg_begin(), AE = ME->arg_end();
|
||||
if (const Expr *Receiver = ME->getInstanceReceiver()) {
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Receiver, Pred, Tmp);
|
||||
|
||||
|
@ -2405,8 +2410,9 @@ void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
|
|||
// Transfer functions: Miscellaneous statements.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst, bool asLValue) {
|
||||
void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst,
|
||||
bool asLValue) {
|
||||
ExplodedNodeSet S1;
|
||||
QualType T = CastE->getType();
|
||||
QualType ExTy = Ex->getType();
|
||||
|
@ -2495,11 +2501,12 @@ void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
|
||||
void GRExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst,
|
||||
bool asLValue) {
|
||||
InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
|
||||
const InitListExpr* ILE
|
||||
= cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(ILE, Pred, Tmp);
|
||||
|
||||
|
@ -2517,17 +2524,17 @@ void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
|
||||
// The CFG has one DeclStmt per Decl.
|
||||
Decl* D = *DS->decl_begin();
|
||||
const Decl* D = *DS->decl_begin();
|
||||
|
||||
if (!D || !isa<VarDecl>(D))
|
||||
return;
|
||||
|
||||
const VarDecl* VD = dyn_cast<VarDecl>(D);
|
||||
Expr* InitEx = const_cast<Expr*>(VD->getInit());
|
||||
const Expr* InitEx = const_cast<Expr*>(VD->getInit());
|
||||
|
||||
// FIXME: static variables may have an initializer, but the second
|
||||
// time a function is called those values may not be current.
|
||||
|
@ -2580,10 +2587,10 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
|
||||
void GRExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
|
||||
ExplodedNode *Pred, ExplodedNodeSet& Dst) {
|
||||
|
||||
Expr* InitEx = VD->getInit();
|
||||
const Expr* InitEx = VD->getInit();
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(InitEx, Pred, Tmp);
|
||||
|
||||
|
@ -2614,16 +2621,16 @@ class InitListWLItem {
|
|||
public:
|
||||
llvm::ImmutableList<SVal> Vals;
|
||||
ExplodedNode* N;
|
||||
InitListExpr::reverse_iterator Itr;
|
||||
InitListExpr::const_reverse_iterator Itr;
|
||||
|
||||
InitListWLItem(ExplodedNode* n, llvm::ImmutableList<SVal> vals,
|
||||
InitListExpr::reverse_iterator itr)
|
||||
InitListExpr::const_reverse_iterator itr)
|
||||
: Vals(vals), N(n), Itr(itr) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
|
||||
const GRState* state = GetState(Pred);
|
||||
|
@ -2645,7 +2652,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
|||
llvm::SmallVector<InitListWLItem, 10> WorkList;
|
||||
WorkList.reserve(NumInitElements);
|
||||
WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
|
||||
InitListExpr::reverse_iterator ItrEnd = E->rend();
|
||||
InitListExpr::const_reverse_iterator ItrEnd = E->rend();
|
||||
assert(!(E->rbegin() == E->rend()));
|
||||
|
||||
// Process the worklist until it is empty.
|
||||
|
@ -2656,7 +2663,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
|||
ExplodedNodeSet Tmp;
|
||||
Visit(*X.Itr, X.N, Tmp);
|
||||
|
||||
InitListExpr::reverse_iterator NewItr = X.Itr + 1;
|
||||
InitListExpr::const_reverse_iterator NewItr = X.Itr + 1;
|
||||
|
||||
for (ExplodedNodeSet::iterator NI=Tmp.begin(),NE=Tmp.end();NI!=NE;++NI) {
|
||||
// Get the last initializer value.
|
||||
|
@ -2688,7 +2695,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
|||
if (Loc::IsLocType(T) || T->isIntegerType()) {
|
||||
assert (E->getNumInits() == 1);
|
||||
ExplodedNodeSet Tmp;
|
||||
Expr* Init = E->getInit(0);
|
||||
const Expr* Init = E->getInit(0);
|
||||
Visit(Init, Pred, Tmp);
|
||||
for (ExplodedNodeSet::iterator I=Tmp.begin(), EI=Tmp.end(); I != EI; ++I) {
|
||||
state = GetState(*I);
|
||||
|
@ -2701,7 +2708,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
|
|||
}
|
||||
|
||||
/// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type).
|
||||
void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
|
||||
void GRExprEngine::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
QualType T = Ex->getTypeOfArgument();
|
||||
|
@ -2724,7 +2731,7 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
|
|||
|
||||
// Get the size by getting the extent of the sub-expression.
|
||||
// First, visit the sub-expression to find its region.
|
||||
Expr *Arg = Ex->getArgumentExpr();
|
||||
const Expr *Arg = Ex->getArgumentExpr();
|
||||
ExplodedNodeSet Tmp;
|
||||
VisitLValue(Arg, Pred, Tmp);
|
||||
|
||||
|
@ -2766,8 +2773,8 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
|
|||
ValMgr.makeIntVal(amt.getQuantity(), Ex->getType())));
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitOffsetOfExpr(OffsetOfExpr* OOE, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
void GRExprEngine::VisitOffsetOfExpr(const OffsetOfExpr* OOE,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
Expr::EvalResult Res;
|
||||
if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) {
|
||||
const APSInt &IV = Res.Val.getInt();
|
||||
|
@ -2782,7 +2789,8 @@ void GRExprEngine::VisitOffsetOfExpr(OffsetOfExpr* OOE, ExplodedNode* Pred,
|
|||
Dst.Add(Pred);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue) {
|
||||
|
||||
switch (U->getOpcode()) {
|
||||
|
@ -2792,7 +2800,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
|
||||
case UnaryOperator::Deref: {
|
||||
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
||||
|
@ -2813,7 +2821,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
|
||||
case UnaryOperator::Real: {
|
||||
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
||||
|
@ -2837,7 +2845,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
|
||||
case UnaryOperator::Imag: {
|
||||
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
||||
|
@ -2882,7 +2890,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
// generate an extra node that just propagates the value of the
|
||||
// subexpression.
|
||||
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
|
||||
if (asLValue)
|
||||
|
@ -2901,7 +2909,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
case UnaryOperator::AddrOf: {
|
||||
|
||||
assert(!asLValue);
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
VisitLValue(Ex, Pred, Tmp);
|
||||
|
||||
|
@ -2920,7 +2928,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
case UnaryOperator::Not: {
|
||||
|
||||
assert (!asLValue);
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
ExplodedNodeSet Tmp;
|
||||
Visit(Ex, Pred, Tmp);
|
||||
|
||||
|
@ -2996,7 +3004,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
|
||||
assert (U->isIncrementDecrementOp());
|
||||
ExplodedNodeSet Tmp;
|
||||
Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
const Expr* Ex = U->getSubExpr()->IgnoreParens();
|
||||
VisitLValue(Ex, Pred, Tmp);
|
||||
|
||||
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
|
||||
|
@ -3071,14 +3079,14 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred,
|
||||
void GRExprEngine::VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
|
||||
AsmStmt::outputs_iterator I,
|
||||
AsmStmt::outputs_iterator E,
|
||||
void GRExprEngine::VisitAsmStmtHelperOutputs(const AsmStmt* A,
|
||||
AsmStmt::const_outputs_iterator I,
|
||||
AsmStmt::const_outputs_iterator E,
|
||||
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
if (I == E) {
|
||||
VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
|
||||
|
@ -3094,9 +3102,9 @@ void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
|
|||
VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
|
||||
AsmStmt::inputs_iterator I,
|
||||
AsmStmt::inputs_iterator E,
|
||||
void GRExprEngine::VisitAsmStmtHelperInputs(const AsmStmt* A,
|
||||
AsmStmt::const_inputs_iterator I,
|
||||
AsmStmt::const_inputs_iterator E,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst) {
|
||||
if (I == E) {
|
||||
|
@ -3110,7 +3118,7 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
|
|||
|
||||
const GRState* state = GetState(Pred);
|
||||
|
||||
for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
|
||||
for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
|
||||
OE = A->end_outputs(); OI != OE; ++OI) {
|
||||
|
||||
SVal X = state->getSVal(*OI);
|
||||
|
@ -3133,10 +3141,10 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
|
|||
VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
|
||||
void GRExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
ExplodedNodeSet Src;
|
||||
if (Expr *RetE = RS->getRetValue()) {
|
||||
if (const Expr *RetE = RS->getRetValue()) {
|
||||
// Record the returned expression in the state. It will be used in
|
||||
// ProcessCallExit to bind the return value to the call expr.
|
||||
{
|
||||
|
@ -3181,7 +3189,7 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
|
|||
// Transfer functions: Binary operators.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
||||
void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
||||
ExplodedNode* Pred,
|
||||
ExplodedNodeSet& Dst, bool asLValue) {
|
||||
|
||||
|
@ -3471,7 +3479,7 @@ struct DOTGraphTraits<ExplodedNode*> :
|
|||
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
|
||||
<< E.getDst()->getBlockID() << ')';
|
||||
|
||||
if (Stmt* T = E.getSrc()->getTerminator()) {
|
||||
if (const Stmt* T = E.getSrc()->getTerminator()) {
|
||||
|
||||
SourceLocation SLoc = T->getLocStart();
|
||||
|
||||
|
@ -3487,15 +3495,15 @@ struct DOTGraphTraits<ExplodedNode*> :
|
|||
}
|
||||
|
||||
if (isa<SwitchStmt>(T)) {
|
||||
Stmt* Label = E.getDst()->getLabel();
|
||||
const Stmt* Label = E.getDst()->getLabel();
|
||||
|
||||
if (Label) {
|
||||
if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
|
||||
if (const CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
|
||||
Out << "\\lcase ";
|
||||
LangOptions LO; // FIXME.
|
||||
C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
|
||||
|
||||
if (Stmt* RHS = C->getRHS()) {
|
||||
if (const Stmt* RHS = C->getRHS()) {
|
||||
Out << " .. ";
|
||||
RHS->printPretty(Out, 0, PrintingPolicy(LO));
|
||||
}
|
||||
|
|
|
@ -29,27 +29,28 @@ class UndefBranchChecker : public Checker {
|
|||
|
||||
FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
|
||||
|
||||
Expr* FindExpr(Expr* Ex) {
|
||||
const Expr* FindExpr(const Expr* Ex) {
|
||||
if (!MatchesCriteria(Ex))
|
||||
return 0;
|
||||
|
||||
for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
|
||||
if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
|
||||
Expr* E2 = FindExpr(ExI);
|
||||
for (Stmt::const_child_iterator I = Ex->child_begin(),
|
||||
E = Ex->child_end();I!=E;++I)
|
||||
if (const Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
|
||||
const Expr* E2 = FindExpr(ExI);
|
||||
if (E2) return E2;
|
||||
}
|
||||
|
||||
return Ex;
|
||||
}
|
||||
|
||||
bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
|
||||
bool MatchesCriteria(const Expr* Ex) { return St->getSVal(Ex).isUndef(); }
|
||||
};
|
||||
|
||||
public:
|
||||
UndefBranchChecker() : BT(0) {}
|
||||
static void *getTag();
|
||||
void VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng,
|
||||
Stmt *Condition, void *tag);
|
||||
const Stmt *Condition, void *tag);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ void *UndefBranchChecker::getTag() {
|
|||
|
||||
void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder,
|
||||
GRExprEngine &Eng,
|
||||
Stmt *Condition, void *tag) {
|
||||
const Stmt *Condition, void *tag){
|
||||
const GRState *state = Builder.getState();
|
||||
SVal X = state->getSVal(Condition);
|
||||
if (X.isUndef()) {
|
||||
|
@ -81,7 +82,7 @@ void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder,
|
|||
// subexpressions and roughly look for the most nested subexpression
|
||||
// that binds to Undefined. We then highlight that expression's range.
|
||||
BlockEdge B = cast<BlockEdge>(N->getLocation());
|
||||
Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
|
||||
const Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
|
||||
assert (Ex && "Block must have a terminator.");
|
||||
|
||||
// Get the predecessor node and check if is a PostStmt with the Stmt
|
||||
|
|
Loading…
Reference in New Issue