forked from OSchip/llvm-project
Change references to 'const ProgramState *' to typedef 'ProgramStateRef'.
At this point this is largely cosmetic, but it opens the door to replace ProgramStateRef with a smart pointer that more eagerly acts in the role of reclaiming unused ProgramState objects. llvm-svn: 149081
This commit is contained in:
parent
6efba4fc97
commit
49b1e38e4b
|
@ -18,17 +18,10 @@
|
||||||
|
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
|
||||||
#include "llvm/ADT/APSInt.h"
|
|
||||||
#include "llvm/ADT/ImmutableList.h"
|
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
namespace ento {
|
namespace ento {
|
||||||
|
|
||||||
class ProgramState;
|
|
||||||
|
|
||||||
class CompoundValData : public llvm::FoldingSetNode {
|
class CompoundValData : public llvm::FoldingSetNode {
|
||||||
QualType T;
|
QualType T;
|
||||||
llvm::ImmutableList<SVal> L;
|
llvm::ImmutableList<SVal> L;
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
/// the state of the program before the checker ran. Note, checkers should
|
/// the state of the program before the checker ran. Note, checkers should
|
||||||
/// not retain the node in their state since the nodes might get invalidated.
|
/// not retain the node in their state since the nodes might get invalidated.
|
||||||
ExplodedNode *getPredecessor() { return Pred; }
|
ExplodedNode *getPredecessor() { return Pred; }
|
||||||
const ProgramState *getState() const { return Pred->getState(); }
|
ProgramStateRef getState() const { return Pred->getState(); }
|
||||||
|
|
||||||
/// \brief Returns the number of times the current block has been visited
|
/// \brief Returns the number of times the current block has been visited
|
||||||
/// along the analyzed path.
|
/// along the analyzed path.
|
||||||
|
@ -111,7 +111,7 @@ public:
|
||||||
/// tag is specified, a default tag, unique to the given checker,
|
/// tag is specified, a default tag, unique to the given checker,
|
||||||
/// will be used. Tags are used to prevent states generated at
|
/// will be used. Tags are used to prevent states generated at
|
||||||
/// different sites from caching out.
|
/// different sites from caching out.
|
||||||
ExplodedNode *addTransition(const ProgramState *State,
|
ExplodedNode *addTransition(ProgramStateRef State,
|
||||||
const ProgramPointTag *Tag = 0) {
|
const ProgramPointTag *Tag = 0) {
|
||||||
return addTransitionImpl(State, false, 0, Tag);
|
return addTransitionImpl(State, false, 0, Tag);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ public:
|
||||||
/// @param Tag The tag to uniquely identify the creation site.
|
/// @param Tag The tag to uniquely identify the creation site.
|
||||||
/// @param IsSink Mark the new node as sink, which will stop exploration of
|
/// @param IsSink Mark the new node as sink, which will stop exploration of
|
||||||
/// the given path.
|
/// the given path.
|
||||||
ExplodedNode *addTransition(const ProgramState *State,
|
ExplodedNode *addTransition(ProgramStateRef State,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramPointTag *Tag = 0,
|
const ProgramPointTag *Tag = 0,
|
||||||
bool IsSink = false) {
|
bool IsSink = false) {
|
||||||
|
@ -140,7 +140,7 @@ public:
|
||||||
|
|
||||||
/// \brief Generate a sink node. Generating sink stops exploration of the
|
/// \brief Generate a sink node. Generating sink stops exploration of the
|
||||||
/// given path.
|
/// given path.
|
||||||
ExplodedNode *generateSink(const ProgramState *state = 0) {
|
ExplodedNode *generateSink(ProgramStateRef state = 0) {
|
||||||
return addTransitionImpl(state ? state : getState(), true);
|
return addTransitionImpl(state ? state : getState(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public:
|
||||||
StringRef getMacroNameOrSpelling(SourceLocation &Loc);
|
StringRef getMacroNameOrSpelling(SourceLocation &Loc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExplodedNode *addTransitionImpl(const ProgramState *State,
|
ExplodedNode *addTransitionImpl(ProgramStateRef State,
|
||||||
bool MarkAsSink,
|
bool MarkAsSink,
|
||||||
ExplodedNode *P = 0,
|
ExplodedNode *P = 0,
|
||||||
const ProgramPointTag *Tag = 0) {
|
const ProgramPointTag *Tag = 0) {
|
||||||
|
|
|
@ -22,46 +22,43 @@ class APSInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
namespace ento {
|
namespace ento {
|
||||||
|
|
||||||
class ProgramState;
|
|
||||||
class ProgramStateManager;
|
|
||||||
class SubEngine;
|
class SubEngine;
|
||||||
|
|
||||||
class ConstraintManager {
|
class ConstraintManager {
|
||||||
public:
|
public:
|
||||||
virtual ~ConstraintManager();
|
virtual ~ConstraintManager();
|
||||||
virtual const ProgramState *assume(const ProgramState *state,
|
virtual ProgramStateRef assume(ProgramStateRef state,
|
||||||
DefinedSVal Cond,
|
DefinedSVal Cond,
|
||||||
bool Assumption) = 0;
|
bool Assumption) = 0;
|
||||||
|
|
||||||
std::pair<const ProgramState*, const ProgramState*>
|
std::pair<ProgramStateRef , ProgramStateRef >
|
||||||
assumeDual(const ProgramState *state, DefinedSVal Cond)
|
assumeDual(ProgramStateRef state, DefinedSVal Cond)
|
||||||
{
|
{
|
||||||
std::pair<const ProgramState*, const ProgramState*> res =
|
std::pair<ProgramStateRef , ProgramStateRef > res =
|
||||||
std::make_pair(assume(state, Cond, true), assume(state, Cond, false));
|
std::make_pair(assume(state, Cond, true), assume(state, Cond, false));
|
||||||
|
|
||||||
assert(!(!res.first && !res.second) && "System is over constrained.");
|
assert(!(!res.first && !res.second) && "System is over constrained.");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const llvm::APSInt* getSymVal(const ProgramState *state,
|
virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
|
||||||
SymbolRef sym) const = 0;
|
SymbolRef sym) const = 0;
|
||||||
|
|
||||||
virtual bool isEqual(const ProgramState *state,
|
virtual bool isEqual(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) const = 0;
|
const llvm::APSInt& V) const = 0;
|
||||||
|
|
||||||
virtual const ProgramState *removeDeadBindings(const ProgramState *state,
|
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
|
||||||
SymbolReaper& SymReaper) = 0;
|
SymbolReaper& SymReaper) = 0;
|
||||||
|
|
||||||
virtual void print(const ProgramState *state,
|
virtual void print(ProgramStateRef state,
|
||||||
raw_ostream &Out,
|
raw_ostream &Out,
|
||||||
const char* nl,
|
const char* nl,
|
||||||
const char *sep) = 0;
|
const char *sep) = 0;
|
||||||
|
|
||||||
virtual void EndPath(const ProgramState *state) {}
|
virtual void EndPath(ProgramStateRef state) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
|
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
|
||||||
|
|
|
@ -79,7 +79,7 @@ private:
|
||||||
BlocksAborted blocksAborted;
|
BlocksAborted blocksAborted;
|
||||||
|
|
||||||
void generateNode(const ProgramPoint &Loc,
|
void generateNode(const ProgramPoint &Loc,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
ExplodedNode *Pred);
|
ExplodedNode *Pred);
|
||||||
|
|
||||||
void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
|
void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
|
||||||
|
@ -128,10 +128,10 @@ public:
|
||||||
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
|
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
|
||||||
/// steps. Returns true if there is still simulation state on the worklist.
|
/// steps. Returns true if there is still simulation state on the worklist.
|
||||||
bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
|
bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
|
||||||
const ProgramState *InitState);
|
ProgramStateRef InitState);
|
||||||
void ExecuteWorkListWithInitialState(const LocationContext *L,
|
void ExecuteWorkListWithInitialState(const LocationContext *L,
|
||||||
unsigned Steps,
|
unsigned Steps,
|
||||||
const ProgramState *InitState,
|
ProgramStateRef InitState,
|
||||||
ExplodedNodeSet &Dst);
|
ExplodedNodeSet &Dst);
|
||||||
|
|
||||||
// Functions for external checking of whether we have unfinished work
|
// Functions for external checking of whether we have unfinished work
|
||||||
|
@ -237,7 +237,7 @@ protected:
|
||||||
virtual void finalizeResults() {}
|
virtual void finalizeResults() {}
|
||||||
|
|
||||||
ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
|
ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
bool MarkAsSink = false);
|
bool MarkAsSink = false);
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ public:
|
||||||
/// When a node is marked as sink, the exploration from the node is stopped -
|
/// When a node is marked as sink, the exploration from the node is stopped -
|
||||||
/// the node becomes the last node on the path.
|
/// the node becomes the last node on the path.
|
||||||
ExplodedNode *generateNode(const ProgramPoint &PP,
|
ExplodedNode *generateNode(const ProgramPoint &PP,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
bool MarkAsSink = false) {
|
bool MarkAsSink = false) {
|
||||||
return generateNodeImpl(PP, State, Pred, MarkAsSink);
|
return generateNodeImpl(PP, State, Pred, MarkAsSink);
|
||||||
|
@ -310,7 +310,7 @@ public:
|
||||||
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
|
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
|
||||||
const NodeBuilderContext &Ctx, ProgramPoint &L)
|
const NodeBuilderContext &Ctx, ProgramPoint &L)
|
||||||
: NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
|
: NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
|
||||||
ExplodedNode *generateNode(const ProgramState *State,
|
ExplodedNode *generateNode(ProgramStateRef State,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramPointTag *Tag = 0,
|
const ProgramPointTag *Tag = 0,
|
||||||
bool MarkAsSink = false) {
|
bool MarkAsSink = false) {
|
||||||
|
@ -358,7 +358,7 @@ public:
|
||||||
|
|
||||||
ExplodedNode *generateNode(const Stmt *S,
|
ExplodedNode *generateNode(const Stmt *S,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *St,
|
ProgramStateRef St,
|
||||||
bool MarkAsSink = false,
|
bool MarkAsSink = false,
|
||||||
const ProgramPointTag *tag = 0,
|
const ProgramPointTag *tag = 0,
|
||||||
ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
|
ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
|
||||||
|
@ -369,7 +369,7 @@ public:
|
||||||
|
|
||||||
ExplodedNode *generateNode(const ProgramPoint &PP,
|
ExplodedNode *generateNode(const ProgramPoint &PP,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
bool MarkAsSink = false) {
|
bool MarkAsSink = false) {
|
||||||
return generateNodeImpl(PP, State, Pred, MarkAsSink);
|
return generateNodeImpl(PP, State, Pred, MarkAsSink);
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ public:
|
||||||
takeNodes(SrcSet);
|
takeNodes(SrcSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplodedNode *generateNode(const ProgramState *State, bool branch,
|
ExplodedNode *generateNode(ProgramStateRef State, bool branch,
|
||||||
ExplodedNode *Pred);
|
ExplodedNode *Pred);
|
||||||
|
|
||||||
const CFGBlock *getTargetBlock(bool branch) const {
|
const CFGBlock *getTargetBlock(bool branch) const {
|
||||||
|
@ -458,12 +458,12 @@ public:
|
||||||
iterator end() { return iterator(DispatchBlock.succ_end()); }
|
iterator end() { return iterator(DispatchBlock.succ_end()); }
|
||||||
|
|
||||||
ExplodedNode *generateNode(const iterator &I,
|
ExplodedNode *generateNode(const iterator &I,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
bool isSink = false);
|
bool isSink = false);
|
||||||
|
|
||||||
const Expr *getTarget() const { return E; }
|
const Expr *getTarget() const { return E; }
|
||||||
|
|
||||||
const ProgramState *getState() const { return Pred->State; }
|
ProgramStateRef getState() const { return Pred->State; }
|
||||||
|
|
||||||
const LocationContext *getLocationContext() const {
|
const LocationContext *getLocationContext() const {
|
||||||
return Pred->getLocationContext();
|
return Pred->getLocationContext();
|
||||||
|
@ -509,14 +509,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplodedNode *generateCaseStmtNode(const iterator &I,
|
ExplodedNode *generateCaseStmtNode(const iterator &I,
|
||||||
const ProgramState *State);
|
ProgramStateRef State);
|
||||||
|
|
||||||
ExplodedNode *generateDefaultCaseNode(const ProgramState *State,
|
ExplodedNode *generateDefaultCaseNode(ProgramStateRef State,
|
||||||
bool isSink = false);
|
bool isSink = false);
|
||||||
|
|
||||||
const Expr *getCondition() const { return Condition; }
|
const Expr *getCondition() const { return Condition; }
|
||||||
|
|
||||||
const ProgramState *getState() const { return Pred->State; }
|
ProgramStateRef getState() const { return Pred->State; }
|
||||||
|
|
||||||
const LocationContext *getLocationContext() const {
|
const LocationContext *getLocationContext() const {
|
||||||
return Pred->getLocationContext();
|
return Pred->getLocationContext();
|
||||||
|
|
|
@ -129,7 +129,7 @@ public:
|
||||||
|
|
||||||
Environment removeDeadBindings(Environment Env,
|
Environment removeDeadBindings(Environment Env,
|
||||||
SymbolReaper &SymReaper,
|
SymbolReaper &SymReaper,
|
||||||
const ProgramState *state);
|
ProgramStateRef state);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end GR namespace
|
} // end GR namespace
|
||||||
|
|
|
@ -106,7 +106,7 @@ class ExplodedNode : public llvm::FoldingSetNode {
|
||||||
const ProgramPoint Location;
|
const ProgramPoint Location;
|
||||||
|
|
||||||
/// State - The state associated with this node.
|
/// State - The state associated with this node.
|
||||||
const ProgramState *State;
|
ProgramStateRef State;
|
||||||
|
|
||||||
/// Preds - The predecessors of this node.
|
/// Preds - The predecessors of this node.
|
||||||
NodeGroup Preds;
|
NodeGroup Preds;
|
||||||
|
@ -116,7 +116,7 @@ class ExplodedNode : public llvm::FoldingSetNode {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state,
|
explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
|
||||||
bool IsSink)
|
bool IsSink)
|
||||||
: Location(loc), State(state) {
|
: Location(loc), State(state) {
|
||||||
const_cast<ProgramState*>(State)->incrementReferenceCount();
|
const_cast<ProgramState*>(State)->incrementReferenceCount();
|
||||||
|
@ -146,14 +146,14 @@ public:
|
||||||
return *getLocationContext()->getAnalysis<T>();
|
return *getLocationContext()->getAnalysis<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *getState() const { return State; }
|
ProgramStateRef getState() const { return State; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
|
const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
|
||||||
|
|
||||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||||
const ProgramPoint &Loc,
|
const ProgramPoint &Loc,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
bool IsSink) {
|
bool IsSink) {
|
||||||
ID.Add(Loc);
|
ID.Add(Loc);
|
||||||
ID.AddPointer(state);
|
ID.AddPointer(state);
|
||||||
|
@ -285,7 +285,7 @@ public:
|
||||||
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
|
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
|
||||||
/// this pair exists, it is created. IsNew is set to true if
|
/// this pair exists, it is created. IsNew is set to true if
|
||||||
/// the node was freshly created.
|
/// the node was freshly created.
|
||||||
ExplodedNode *getNode(const ProgramPoint &L, const ProgramState *State,
|
ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State,
|
||||||
bool IsSink = false,
|
bool IsSink = false,
|
||||||
bool* IsNew = 0);
|
bool* IsNew = 0);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ExprEngine : public SubEngine {
|
||||||
|
|
||||||
/// CleanedState - The state for EntryNode "cleaned" of all dead
|
/// CleanedState - The state for EntryNode "cleaned" of all dead
|
||||||
/// variables and symbols (as determined by a liveness analysis).
|
/// variables and symbols (as determined by a liveness analysis).
|
||||||
const ProgramState *CleanedState;
|
ProgramStateRef CleanedState;
|
||||||
|
|
||||||
/// currentStmt - The current block-level statement.
|
/// currentStmt - The current block-level statement.
|
||||||
const Stmt *currentStmt;
|
const Stmt *currentStmt;
|
||||||
|
@ -96,7 +96,7 @@ public:
|
||||||
/// of the function are added into the Dst set, which represent the exit
|
/// of the function are added into the Dst set, which represent the exit
|
||||||
/// state of the function call.
|
/// state of the function call.
|
||||||
void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
|
void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
|
||||||
const ProgramState *InitState,
|
ProgramStateRef InitState,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
|
Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ public:
|
||||||
|
|
||||||
/// getInitialState - Return the initial state used for the root vertex
|
/// getInitialState - Return the initial state used for the root vertex
|
||||||
/// in the ExplodedGraph.
|
/// in the ExplodedGraph.
|
||||||
const ProgramState *getInitialState(const LocationContext *InitLoc);
|
ProgramStateRef getInitialState(const LocationContext *InitLoc);
|
||||||
|
|
||||||
ExplodedGraph& getGraph() { return G; }
|
ExplodedGraph& getGraph() { return G; }
|
||||||
const ExplodedGraph& getGraph() const { return G; }
|
const ExplodedGraph& getGraph() const { return G; }
|
||||||
|
@ -195,22 +195,22 @@ public:
|
||||||
|
|
||||||
/// evalAssume - Callback function invoked by the ConstraintManager when
|
/// evalAssume - Callback function invoked by the ConstraintManager when
|
||||||
/// making assumptions about state values.
|
/// making assumptions about state values.
|
||||||
const ProgramState *processAssume(const ProgramState *state, SVal cond,bool assumption);
|
ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption);
|
||||||
|
|
||||||
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
|
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
|
||||||
/// region change should trigger a processRegionChanges update.
|
/// region change should trigger a processRegionChanges update.
|
||||||
bool wantsRegionChangeUpdate(const ProgramState *state);
|
bool wantsRegionChangeUpdate(ProgramStateRef state);
|
||||||
|
|
||||||
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
|
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
|
||||||
/// to the store. Used to update checkers that track region values.
|
/// to the store. Used to update checkers that track region values.
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
processRegionChanges(const ProgramState *state,
|
processRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions);
|
ArrayRef<const MemRegion *> Regions);
|
||||||
|
|
||||||
/// printState - Called by ProgramStateManager to print checker-specific data.
|
/// printState - Called by ProgramStateManager to print checker-specific data.
|
||||||
void printState(raw_ostream &Out, const ProgramState *State,
|
void printState(raw_ostream &Out, ProgramStateRef State,
|
||||||
const char *NL, const char *Sep);
|
const char *NL, const char *Sep);
|
||||||
|
|
||||||
virtual ProgramStateManager& getStateManager() { return StateMgr; }
|
virtual ProgramStateManager& getStateManager() { return StateMgr; }
|
||||||
|
@ -409,31 +409,31 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
|
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
NonLoc L, NonLoc R, QualType T) {
|
NonLoc L, NonLoc R, QualType T) {
|
||||||
return svalBuilder.evalBinOpNN(state, op, L, R, T);
|
return svalBuilder.evalBinOpNN(state, op, L, R, T);
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
|
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
NonLoc L, SVal R, QualType T) {
|
NonLoc L, SVal R, QualType T) {
|
||||||
return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
|
return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal evalBinOp(const ProgramState *ST, BinaryOperator::Opcode Op,
|
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
|
||||||
SVal LHS, SVal RHS, QualType T) {
|
SVal LHS, SVal RHS, QualType T) {
|
||||||
return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
|
return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMessage &msg,
|
void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMessage &msg,
|
||||||
ExplodedNode *Pred, const ProgramState *state,
|
ExplodedNode *Pred, ProgramStateRef state,
|
||||||
bool GenSink);
|
bool GenSink);
|
||||||
|
|
||||||
const ProgramState *invalidateArguments(const ProgramState *State,
|
ProgramStateRef invalidateArguments(ProgramStateRef State,
|
||||||
const CallOrObjCMessage &Call,
|
const CallOrObjCMessage &Call,
|
||||||
const LocationContext *LC);
|
const LocationContext *LC);
|
||||||
|
|
||||||
const ProgramState *MarkBranch(const ProgramState *state,
|
ProgramStateRef MarkBranch(ProgramStateRef state,
|
||||||
const Stmt *Terminator,
|
const Stmt *Terminator,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
bool branchTaken);
|
bool branchTaken);
|
||||||
|
@ -452,23 +452,23 @@ public:
|
||||||
// same as state->getLValue(Ex).
|
// same as state->getLValue(Ex).
|
||||||
/// Simulate a read of the result of Ex.
|
/// Simulate a read of the result of Ex.
|
||||||
void evalLoad(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred,
|
void evalLoad(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred,
|
||||||
const ProgramState *St, SVal location, const ProgramPointTag *tag = 0,
|
ProgramStateRef St, SVal location, const ProgramPointTag *tag = 0,
|
||||||
QualType LoadTy = QualType());
|
QualType LoadTy = QualType());
|
||||||
|
|
||||||
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
||||||
// instead.
|
// instead.
|
||||||
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
|
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
|
||||||
ExplodedNode *Pred, const ProgramState *St, SVal TargetLV, SVal Val,
|
ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
|
||||||
const ProgramPointTag *tag = 0);
|
const ProgramPointTag *tag = 0);
|
||||||
private:
|
private:
|
||||||
void evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred,
|
void evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred,
|
||||||
const ProgramState *St, SVal location, const ProgramPointTag *tag,
|
ProgramStateRef St, SVal location, const ProgramPointTag *tag,
|
||||||
QualType LoadTy);
|
QualType LoadTy);
|
||||||
|
|
||||||
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
||||||
// instead.
|
// instead.
|
||||||
void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode *Pred,
|
void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode *Pred,
|
||||||
const ProgramState *St, SVal location,
|
ProgramStateRef St, SVal location,
|
||||||
const ProgramPointTag *tag, bool isLoad);
|
const ProgramPointTag *tag, bool isLoad);
|
||||||
|
|
||||||
bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
|
bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal getInstanceReceiverSVal(const ProgramState *State,
|
SVal getInstanceReceiverSVal(ProgramStateRef State,
|
||||||
const LocationContext *LC) const {
|
const LocationContext *LC) const {
|
||||||
assert(isValid() && "This ObjCMessage is uninitialized!");
|
assert(isValid() && "This ObjCMessage is uninitialized!");
|
||||||
if (!isInstanceMessage())
|
if (!isInstanceMessage())
|
||||||
|
@ -143,7 +143,7 @@ public:
|
||||||
|
|
||||||
SVal getArgSVal(unsigned i,
|
SVal getArgSVal(unsigned i,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
const ProgramState *state) const {
|
ProgramStateRef state) const {
|
||||||
assert(isValid() && "This ObjCMessage is uninitialized!");
|
assert(isValid() && "This ObjCMessage is uninitialized!");
|
||||||
assert(i < getNumArgs() && "Invalid index for argument");
|
assert(i < getNumArgs() && "Invalid index for argument");
|
||||||
if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
|
if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
|
||||||
|
@ -208,16 +208,16 @@ public:
|
||||||
class CallOrObjCMessage {
|
class CallOrObjCMessage {
|
||||||
llvm::PointerUnion<const CallExpr *, const CXXConstructExpr *> CallE;
|
llvm::PointerUnion<const CallExpr *, const CXXConstructExpr *> CallE;
|
||||||
ObjCMessage Msg;
|
ObjCMessage Msg;
|
||||||
const ProgramState *State;
|
ProgramStateRef State;
|
||||||
const LocationContext *LCtx;
|
const LocationContext *LCtx;
|
||||||
public:
|
public:
|
||||||
CallOrObjCMessage(const CallExpr *callE, const ProgramState *state,
|
CallOrObjCMessage(const CallExpr *callE, ProgramStateRef state,
|
||||||
const LocationContext *lctx)
|
const LocationContext *lctx)
|
||||||
: CallE(callE), State(state), LCtx(lctx) {}
|
: CallE(callE), State(state), LCtx(lctx) {}
|
||||||
CallOrObjCMessage(const CXXConstructExpr *consE, const ProgramState *state,
|
CallOrObjCMessage(const CXXConstructExpr *consE, ProgramStateRef state,
|
||||||
const LocationContext *lctx)
|
const LocationContext *lctx)
|
||||||
: CallE(consE), State(state), LCtx(lctx) {}
|
: CallE(consE), State(state), LCtx(lctx) {}
|
||||||
CallOrObjCMessage(const ObjCMessage &msg, const ProgramState *state,
|
CallOrObjCMessage(const ObjCMessage &msg, ProgramStateRef state,
|
||||||
const LocationContext *lctx)
|
const LocationContext *lctx)
|
||||||
: CallE((CallExpr *)0), Msg(msg), State(state), LCtx(lctx) {}
|
: CallE((CallExpr *)0), Msg(msg), State(state), LCtx(lctx) {}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
|
||||||
|
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
|
||||||
#include "llvm/ADT/PointerIntPair.h"
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
|
@ -35,7 +36,7 @@ class ASTContext;
|
||||||
namespace ento {
|
namespace ento {
|
||||||
|
|
||||||
class CallOrObjCMessage;
|
class CallOrObjCMessage;
|
||||||
class ProgramStateManager;
|
|
||||||
typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
|
typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
|
||||||
SubEngine&);
|
SubEngine&);
|
||||||
typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
|
typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
|
||||||
|
@ -55,8 +56,6 @@ template <typename T> struct ProgramStateTrait {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProgramStateManager;
|
|
||||||
|
|
||||||
/// \class ProgramState
|
/// \class ProgramState
|
||||||
/// ProgramState - This class encapsulates:
|
/// ProgramState - This class encapsulates:
|
||||||
///
|
///
|
||||||
|
@ -89,7 +88,7 @@ private:
|
||||||
|
|
||||||
/// makeWithStore - Return a ProgramState with the same values as the current
|
/// makeWithStore - Return a ProgramState with the same values as the current
|
||||||
/// state with the exception of using the specified Store.
|
/// state with the exception of using the specified Store.
|
||||||
const ProgramState *makeWithStore(const StoreRef &store) const;
|
ProgramStateRef makeWithStore(const StoreRef &store) const;
|
||||||
|
|
||||||
void setStore(const StoreRef &storeRef);
|
void setStore(const StoreRef &storeRef);
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ public:
|
||||||
/// Profile - Profile the contents of a ProgramState object for use in a
|
/// Profile - Profile the contents of a ProgramState object for use in a
|
||||||
/// FoldingSet. Two ProgramState objects are considered equal if they
|
/// FoldingSet. Two ProgramState objects are considered equal if they
|
||||||
/// have the same Environment, Store, and GenericDataMap.
|
/// have the same Environment, Store, and GenericDataMap.
|
||||||
static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
|
static void Profile(llvm::FoldingSetNodeID& ID, ProgramStateRef V) {
|
||||||
V->Env.Profile(ID);
|
V->Env.Profile(ID);
|
||||||
ID.AddPointer(V->store);
|
ID.AddPointer(V->store);
|
||||||
V->GDM.Profile(ID);
|
V->GDM.Profile(ID);
|
||||||
|
@ -169,15 +168,15 @@ public:
|
||||||
// If no new state is feasible, NULL is returned.
|
// If no new state is feasible, NULL is returned.
|
||||||
//
|
//
|
||||||
|
|
||||||
const ProgramState *assume(DefinedOrUnknownSVal cond, bool assumption) const;
|
ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
|
||||||
|
|
||||||
/// This method assumes both "true" and "false" for 'cond', and
|
/// This method assumes both "true" and "false" for 'cond', and
|
||||||
/// returns both corresponding states. It's shorthand for doing
|
/// returns both corresponding states. It's shorthand for doing
|
||||||
/// 'assume' twice.
|
/// 'assume' twice.
|
||||||
std::pair<const ProgramState*, const ProgramState*>
|
std::pair<ProgramStateRef , ProgramStateRef >
|
||||||
assume(DefinedOrUnknownSVal cond) const;
|
assume(DefinedOrUnknownSVal cond) const;
|
||||||
|
|
||||||
const ProgramState *assumeInBound(DefinedOrUnknownSVal idx,
|
ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
|
||||||
DefinedOrUnknownSVal upperBound,
|
DefinedOrUnknownSVal upperBound,
|
||||||
bool assumption) const;
|
bool assumption) const;
|
||||||
|
|
||||||
|
@ -190,44 +189,44 @@ public:
|
||||||
|
|
||||||
/// BindCompoundLiteral - Return the state that has the bindings currently
|
/// BindCompoundLiteral - Return the state that has the bindings currently
|
||||||
/// in this state plus the bindings for the CompoundLiteral.
|
/// in this state plus the bindings for the CompoundLiteral.
|
||||||
const ProgramState *bindCompoundLiteral(const CompoundLiteralExpr *CL,
|
ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL,
|
||||||
const LocationContext *LC,
|
const LocationContext *LC,
|
||||||
SVal V) const;
|
SVal V) const;
|
||||||
|
|
||||||
/// Create a new state by binding the value 'V' to the statement 'S' in the
|
/// Create a new state by binding the value 'V' to the statement 'S' in the
|
||||||
/// state's environment.
|
/// state's environment.
|
||||||
const ProgramState *BindExpr(const Stmt *S, const LocationContext *LCtx,
|
ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
|
||||||
SVal V, bool Invalidate = true) const;
|
SVal V, bool Invalidate = true) const;
|
||||||
|
|
||||||
/// Create a new state by binding the value 'V' and location 'locaton' to the
|
/// Create a new state by binding the value 'V' and location 'locaton' to the
|
||||||
/// statement 'S' in the state's environment.
|
/// statement 'S' in the state's environment.
|
||||||
const ProgramState *bindExprAndLocation(const Stmt *S,
|
ProgramStateRef bindExprAndLocation(const Stmt *S,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
SVal location, SVal V) const;
|
SVal location, SVal V) const;
|
||||||
|
|
||||||
const ProgramState *bindDecl(const VarRegion *VR, SVal V) const;
|
ProgramStateRef bindDecl(const VarRegion *VR, SVal V) const;
|
||||||
|
|
||||||
const ProgramState *bindDeclWithNoInit(const VarRegion *VR) const;
|
ProgramStateRef bindDeclWithNoInit(const VarRegion *VR) const;
|
||||||
|
|
||||||
const ProgramState *bindLoc(Loc location, SVal V) const;
|
ProgramStateRef bindLoc(Loc location, SVal V) const;
|
||||||
|
|
||||||
const ProgramState *bindLoc(SVal location, SVal V) const;
|
ProgramStateRef bindLoc(SVal location, SVal V) const;
|
||||||
|
|
||||||
const ProgramState *bindDefault(SVal loc, SVal V) const;
|
ProgramStateRef bindDefault(SVal loc, SVal V) const;
|
||||||
|
|
||||||
const ProgramState *unbindLoc(Loc LV) const;
|
ProgramStateRef unbindLoc(Loc LV) const;
|
||||||
|
|
||||||
/// invalidateRegions - Returns the state with bindings for the given regions
|
/// invalidateRegions - Returns the state with bindings for the given regions
|
||||||
/// cleared from the store. The regions are provided as a continuous array
|
/// cleared from the store. The regions are provided as a continuous array
|
||||||
/// from Begin to End. Optionally invalidates global regions as well.
|
/// from Begin to End. Optionally invalidates global regions as well.
|
||||||
const ProgramState *invalidateRegions(ArrayRef<const MemRegion *> Regions,
|
ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions,
|
||||||
const Expr *E, unsigned BlockCount,
|
const Expr *E, unsigned BlockCount,
|
||||||
StoreManager::InvalidatedSymbols *IS = 0,
|
StoreManager::InvalidatedSymbols *IS = 0,
|
||||||
const CallOrObjCMessage *Call = 0) const;
|
const CallOrObjCMessage *Call = 0) const;
|
||||||
|
|
||||||
/// enterStackFrame - Returns the state for entry to the given stack frame,
|
/// enterStackFrame - Returns the state for entry to the given stack frame,
|
||||||
/// preserving the current state.
|
/// preserving the current state.
|
||||||
const ProgramState *enterStackFrame(const LocationContext *callerCtx,
|
ProgramStateRef enterStackFrame(const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx) const;
|
const StackFrameContext *calleeCtx) const;
|
||||||
|
|
||||||
/// Get the lvalue for a variable reference.
|
/// Get the lvalue for a variable reference.
|
||||||
|
@ -294,15 +293,15 @@ public:
|
||||||
const MemRegion * const *end) const;
|
const MemRegion * const *end) const;
|
||||||
|
|
||||||
/// Create a new state in which the statement is marked as tainted.
|
/// Create a new state in which the statement is marked as tainted.
|
||||||
const ProgramState* addTaint(const Stmt *S, const LocationContext *LCtx,
|
ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
|
||||||
TaintTagType Kind = TaintTagGeneric) const;
|
TaintTagType Kind = TaintTagGeneric) const;
|
||||||
|
|
||||||
/// Create a new state in which the symbol is marked as tainted.
|
/// Create a new state in which the symbol is marked as tainted.
|
||||||
const ProgramState* addTaint(SymbolRef S,
|
ProgramStateRef addTaint(SymbolRef S,
|
||||||
TaintTagType Kind = TaintTagGeneric) const;
|
TaintTagType Kind = TaintTagGeneric) const;
|
||||||
|
|
||||||
/// Create a new state in which the region symbol is marked as tainted.
|
/// Create a new state in which the region symbol is marked as tainted.
|
||||||
const ProgramState* addTaint(const MemRegion *R,
|
ProgramStateRef addTaint(const MemRegion *R,
|
||||||
TaintTagType Kind = TaintTagGeneric) const;
|
TaintTagType Kind = TaintTagGeneric) const;
|
||||||
|
|
||||||
/// Check if the statement is tainted in the current state.
|
/// Check if the statement is tainted in the current state.
|
||||||
|
@ -319,7 +318,7 @@ public:
|
||||||
void *const* FindGDM(void *K) const;
|
void *const* FindGDM(void *K) const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *add(typename ProgramStateTrait<T>::key_type K) const;
|
ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename ProgramStateTrait<T>::data_type
|
typename ProgramStateTrait<T>::data_type
|
||||||
|
@ -339,23 +338,23 @@ public:
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *remove(typename ProgramStateTrait<T>::key_type K) const;
|
ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *remove(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::context_type C) const;
|
typename ProgramStateTrait<T>::context_type C) const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *remove() const;
|
ProgramStateRef remove() const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *set(typename ProgramStateTrait<T>::data_type D) const;
|
ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *set(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::value_type E) const;
|
typename ProgramStateTrait<T>::value_type E) const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *set(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::value_type E,
|
typename ProgramStateTrait<T>::value_type E,
|
||||||
typename ProgramStateTrait<T>::context_type C) const;
|
typename ProgramStateTrait<T>::context_type C) const;
|
||||||
|
|
||||||
|
@ -385,7 +384,7 @@ private:
|
||||||
--refCount;
|
--refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
||||||
const Expr *E, unsigned BlockCount,
|
const Expr *E, unsigned BlockCount,
|
||||||
StoreManager::InvalidatedSymbols &IS,
|
StoreManager::InvalidatedSymbols &IS,
|
||||||
|
@ -393,12 +392,12 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProgramStateSet {
|
class ProgramStateSet {
|
||||||
typedef llvm::SmallPtrSet<const ProgramState*,5> ImplTy;
|
typedef llvm::SmallPtrSet<ProgramStateRef,5> ImplTy;
|
||||||
ImplTy Impl;
|
ImplTy Impl;
|
||||||
public:
|
public:
|
||||||
ProgramStateSet() {}
|
ProgramStateSet() {}
|
||||||
|
|
||||||
inline void Add(const ProgramState *St) {
|
inline void Add(ProgramStateRef St) {
|
||||||
Impl.insert(St);
|
Impl.insert(St);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,9 +412,9 @@ public:
|
||||||
class AutoPopulate {
|
class AutoPopulate {
|
||||||
ProgramStateSet &S;
|
ProgramStateSet &S;
|
||||||
unsigned StartSize;
|
unsigned StartSize;
|
||||||
const ProgramState *St;
|
ProgramStateRef St;
|
||||||
public:
|
public:
|
||||||
AutoPopulate(ProgramStateSet &s, const ProgramState *st)
|
AutoPopulate(ProgramStateSet &s, ProgramStateRef st)
|
||||||
: S(s), StartSize(S.size()), St(st) {}
|
: S(s), StartSize(S.size()), St(st) {}
|
||||||
|
|
||||||
~AutoPopulate() {
|
~AutoPopulate() {
|
||||||
|
@ -491,7 +490,7 @@ public:
|
||||||
|
|
||||||
~ProgramStateManager();
|
~ProgramStateManager();
|
||||||
|
|
||||||
const ProgramState *getInitialState(const LocationContext *InitLoc);
|
ProgramStateRef getInitialState(const LocationContext *InitLoc);
|
||||||
|
|
||||||
ASTContext &getContext() { return svalBuilder->getContext(); }
|
ASTContext &getContext() { return svalBuilder->getContext(); }
|
||||||
const ASTContext &getContext() const { return svalBuilder->getContext(); }
|
const ASTContext &getContext() const { return svalBuilder->getContext(); }
|
||||||
|
@ -527,13 +526,13 @@ public:
|
||||||
ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
|
ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
|
||||||
SubEngine* getOwningEngine() { return Eng; }
|
SubEngine* getOwningEngine() { return Eng; }
|
||||||
|
|
||||||
const ProgramState *removeDeadBindings(const ProgramState *St,
|
ProgramStateRef removeDeadBindings(ProgramStateRef St,
|
||||||
const StackFrameContext *LCtx,
|
const StackFrameContext *LCtx,
|
||||||
SymbolReaper& SymReaper);
|
SymbolReaper& SymReaper);
|
||||||
|
|
||||||
/// Marshal a new state for the callee in another translation unit.
|
/// Marshal a new state for the callee in another translation unit.
|
||||||
/// 'state' is owned by the caller's engine.
|
/// 'state' is owned by the caller's engine.
|
||||||
const ProgramState *MarshalState(const ProgramState *state, const StackFrameContext *L);
|
ProgramStateRef MarshalState(ProgramStateRef state, const StackFrameContext *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -542,24 +541,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods that manipulate the GDM.
|
// Methods that manipulate the GDM.
|
||||||
const ProgramState *addGDM(const ProgramState *St, void *Key, void *Data);
|
ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
|
||||||
const ProgramState *removeGDM(const ProgramState *state, void *Key);
|
ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
|
||||||
|
|
||||||
// Methods that query & manipulate the Store.
|
// Methods that query & manipulate the Store.
|
||||||
|
|
||||||
void iterBindings(const ProgramState *state, StoreManager::BindingsHandler& F) {
|
void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
|
||||||
StoreMgr->iterBindings(state->getStore(), F);
|
StoreMgr->iterBindings(state->getStore(), F);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *getPersistentState(ProgramState &Impl);
|
ProgramStateRef getPersistentState(ProgramState &Impl);
|
||||||
const ProgramState *getPersistentStateWithGDM(const ProgramState *FromState,
|
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
|
||||||
const ProgramState *GDMState);
|
ProgramStateRef GDMState);
|
||||||
|
|
||||||
bool haveEqualEnvironments(const ProgramState * S1, const ProgramState * S2) {
|
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
|
||||||
return S1->Env == S2->Env;
|
return S1->Env == S2->Env;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool haveEqualStores(const ProgramState * S1, const ProgramState * S2) {
|
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
|
||||||
return S1->store == S2->store;
|
return S1->store == S2->store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,13 +586,13 @@ public:
|
||||||
|
|
||||||
// Trait based GDM dispatch.
|
// Trait based GDM dispatch.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *set(const ProgramState *st, typename ProgramStateTrait<T>::data_type D) {
|
ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
|
||||||
return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
|
return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
|
||||||
ProgramStateTrait<T>::MakeVoidPtr(D));
|
ProgramStateTrait<T>::MakeVoidPtr(D));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *set(const ProgramState *st,
|
ProgramStateRef set(ProgramStateRef st,
|
||||||
typename ProgramStateTrait<T>::key_type K,
|
typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::value_type V,
|
typename ProgramStateTrait<T>::value_type V,
|
||||||
typename ProgramStateTrait<T>::context_type C) {
|
typename ProgramStateTrait<T>::context_type C) {
|
||||||
|
@ -603,7 +602,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *add(const ProgramState *st,
|
ProgramStateRef add(ProgramStateRef st,
|
||||||
typename ProgramStateTrait<T>::key_type K,
|
typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::context_type C) {
|
typename ProgramStateTrait<T>::context_type C) {
|
||||||
return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
|
return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
|
||||||
|
@ -611,7 +610,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *remove(const ProgramState *st,
|
ProgramStateRef remove(ProgramStateRef st,
|
||||||
typename ProgramStateTrait<T>::key_type K,
|
typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::context_type C) {
|
typename ProgramStateTrait<T>::context_type C) {
|
||||||
|
|
||||||
|
@ -620,7 +619,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *remove(const ProgramState *st) {
|
ProgramStateRef remove(ProgramStateRef st) {
|
||||||
return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
|
return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,11 +636,11 @@ public:
|
||||||
return ProgramStateTrait<T>::MakeContext(p);
|
return ProgramStateTrait<T>::MakeContext(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::APSInt* getSymVal(const ProgramState *St, SymbolRef sym) {
|
const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) {
|
||||||
return ConstraintMgr->getSymVal(St, sym);
|
return ConstraintMgr->getSymVal(St, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndPath(const ProgramState *St) {
|
void EndPath(ProgramStateRef St) {
|
||||||
ConstraintMgr->EndPath(St);
|
ConstraintMgr->EndPath(St);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -657,7 +656,7 @@ inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
|
||||||
return getStateManager().getRegionManager().getVarRegion(D, LC);
|
return getStateManager().getRegionManager().getVarRegion(D, LC);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ProgramState *ProgramState::assume(DefinedOrUnknownSVal Cond,
|
inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
|
||||||
bool Assumption) const {
|
bool Assumption) const {
|
||||||
if (Cond.isUnknown())
|
if (Cond.isUnknown())
|
||||||
return this;
|
return this;
|
||||||
|
@ -666,7 +665,7 @@ inline const ProgramState *ProgramState::assume(DefinedOrUnknownSVal Cond,
|
||||||
Assumption);
|
Assumption);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::pair<const ProgramState*, const ProgramState*>
|
inline std::pair<ProgramStateRef , ProgramStateRef >
|
||||||
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
|
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
|
||||||
if (Cond.isUnknown())
|
if (Cond.isUnknown())
|
||||||
return std::make_pair(this, this);
|
return std::make_pair(this, this);
|
||||||
|
@ -675,7 +674,7 @@ ProgramState::assume(DefinedOrUnknownSVal Cond) const {
|
||||||
cast<DefinedSVal>(Cond));
|
cast<DefinedSVal>(Cond));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ProgramState *ProgramState::bindLoc(SVal LV, SVal V) const {
|
inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
|
||||||
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
|
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +747,7 @@ inline SymbolManager &ProgramState::getSymbolManager() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
|
ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
|
||||||
return getStateManager().add<T>(this, K, get_context<T>());
|
return getStateManager().add<T>(this, K, get_context<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,34 +757,34 @@ typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
|
ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
|
||||||
return getStateManager().remove<T>(this, K, get_context<T>());
|
return getStateManager().remove<T>(this, K, get_context<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::context_type C) const {
|
typename ProgramStateTrait<T>::context_type C) const {
|
||||||
return getStateManager().remove<T>(this, K, C);
|
return getStateManager().remove<T>(this, K, C);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const ProgramState *ProgramState::remove() const {
|
ProgramStateRef ProgramState::remove() const {
|
||||||
return getStateManager().remove<T>(this);
|
return getStateManager().remove<T>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
|
ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
|
||||||
return getStateManager().set<T>(this, D);
|
return getStateManager().set<T>(this, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::value_type E) const {
|
typename ProgramStateTrait<T>::value_type E) const {
|
||||||
return getStateManager().set<T>(this, K, E, get_context<T>());
|
return getStateManager().set<T>(this, K, E, get_context<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K,
|
ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
|
||||||
typename ProgramStateTrait<T>::value_type E,
|
typename ProgramStateTrait<T>::value_type E,
|
||||||
typename ProgramStateTrait<T>::context_type C) const {
|
typename ProgramStateTrait<T>::context_type C) const {
|
||||||
return getStateManager().set<T>(this, K, E, C);
|
return getStateManager().set<T>(this, K, E, C);
|
||||||
|
@ -821,12 +820,12 @@ class ScanReachableSymbols : public SubRegionMap::Visitor {
|
||||||
typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
|
typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
|
||||||
|
|
||||||
VisitedItems visited;
|
VisitedItems visited;
|
||||||
const ProgramState *state;
|
ProgramStateRef state;
|
||||||
SymbolVisitor &visitor;
|
SymbolVisitor &visitor;
|
||||||
llvm::OwningPtr<SubRegionMap> SRM;
|
llvm::OwningPtr<SubRegionMap> SRM;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v)
|
ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
|
||||||
: state(st), visitor(v) {}
|
: state(st), visitor(v) {}
|
||||||
|
|
||||||
bool scan(nonloc::CompoundVal val);
|
bool scan(nonloc::CompoundVal val);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
//== ProgramState_Fwd.h - Incomplete declarations of ProgramState -*- C++ -*--=/
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_CLANG_PROGRAMSTATE_FWD_H
|
||||||
|
#define LLVM_CLANG_PROGRAMSTATE_FWD_H
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace ento {
|
||||||
|
class ProgramState;
|
||||||
|
class ProgramStateManager;
|
||||||
|
typedef const ProgramState* ProgramStateRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -22,11 +22,8 @@
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
namespace ento {
|
namespace ento {
|
||||||
|
|
||||||
class ProgramState;
|
|
||||||
|
|
||||||
class SValBuilder {
|
class SValBuilder {
|
||||||
virtual void anchor();
|
virtual void anchor();
|
||||||
protected:
|
protected:
|
||||||
|
@ -88,35 +85,35 @@ public:
|
||||||
|
|
||||||
/// Create a new value which represents a binary expression with two non
|
/// Create a new value which represents a binary expression with two non
|
||||||
/// location operands.
|
/// location operands.
|
||||||
virtual SVal evalBinOpNN(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
|
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
|
||||||
|
|
||||||
/// Create a new value which represents a binary expression with two memory
|
/// Create a new value which represents a binary expression with two memory
|
||||||
/// location operands.
|
/// location operands.
|
||||||
virtual SVal evalBinOpLL(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
Loc lhs, Loc rhs, QualType resultTy) = 0;
|
Loc lhs, Loc rhs, QualType resultTy) = 0;
|
||||||
|
|
||||||
/// Create a new value which represents a binary expression with a memory
|
/// Create a new value which represents a binary expression with a memory
|
||||||
/// location and non location operands. For example, this would be used to
|
/// location and non location operands. For example, this would be used to
|
||||||
/// evaluate a pointer arithmetic operation.
|
/// evaluate a pointer arithmetic operation.
|
||||||
virtual SVal evalBinOpLN(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
|
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
|
||||||
|
|
||||||
/// Evaluates a given SVal. If the SVal has only one possible (integer) value,
|
/// Evaluates a given SVal. If the SVal has only one possible (integer) value,
|
||||||
/// that value is returned. Otherwise, returns NULL.
|
/// that value is returned. Otherwise, returns NULL.
|
||||||
virtual const llvm::APSInt *getKnownValue(const ProgramState *state, SVal val) = 0;
|
virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
|
||||||
|
|
||||||
/// Handles generation of the value in case the builder is not smart enough to
|
/// Handles generation of the value in case the builder is not smart enough to
|
||||||
/// handle the given binary expression. Depending on the state, decides to
|
/// handle the given binary expression. Depending on the state, decides to
|
||||||
/// either keep the expression or forget the history and generate an
|
/// either keep the expression or forget the history and generate an
|
||||||
/// UnknownVal.
|
/// UnknownVal.
|
||||||
SVal makeGenericVal(const ProgramState *state, BinaryOperator::Opcode op,
|
SVal makeGenericVal(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
NonLoc lhs, NonLoc rhs, QualType resultTy);
|
NonLoc lhs, NonLoc rhs, QualType resultTy);
|
||||||
|
|
||||||
SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
|
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
SVal lhs, SVal rhs, QualType type);
|
SVal lhs, SVal rhs, QualType type);
|
||||||
|
|
||||||
DefinedOrUnknownSVal evalEQ(const ProgramState *state, DefinedOrUnknownSVal lhs,
|
DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
|
||||||
DefinedOrUnknownSVal rhs);
|
DefinedOrUnknownSVal rhs);
|
||||||
|
|
||||||
ASTContext &getContext() { return Context; }
|
ASTContext &getContext() { return Context; }
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "clang/Basic/LLVM.h"
|
#include "clang/Basic/LLVM.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
|
||||||
|
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
|
||||||
#include "llvm/ADT/ImmutableList.h"
|
#include "llvm/ADT/ImmutableList.h"
|
||||||
|
|
||||||
//==------------------------------------------------------------------------==//
|
//==------------------------------------------------------------------------==//
|
||||||
|
|
|
@ -115,7 +115,7 @@ public:
|
||||||
|
|
||||||
// FIXME: This should soon be eliminated altogether; clients should deal with
|
// FIXME: This should soon be eliminated altogether; clients should deal with
|
||||||
// region extents directly.
|
// region extents directly.
|
||||||
virtual DefinedOrUnknownSVal getSizeInElements(const ProgramState *state,
|
virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
|
||||||
const MemRegion *region,
|
const MemRegion *region,
|
||||||
QualType EleTy) {
|
QualType EleTy) {
|
||||||
return UnknownVal();
|
return UnknownVal();
|
||||||
|
@ -131,12 +131,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
class CastResult {
|
class CastResult {
|
||||||
const ProgramState *state;
|
ProgramStateRef state;
|
||||||
const MemRegion *region;
|
const MemRegion *region;
|
||||||
public:
|
public:
|
||||||
const ProgramState *getState() const { return state; }
|
ProgramStateRef getState() const { return state; }
|
||||||
const MemRegion* getRegion() const { return region; }
|
const MemRegion* getRegion() const { return region; }
|
||||||
CastResult(const ProgramState *s, const MemRegion* r = 0) : state(s), region(r){}
|
CastResult(ProgramStateRef s, const MemRegion* r = 0) : state(s), region(r){}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
|
const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
|
||||||
|
@ -196,7 +196,7 @@ public:
|
||||||
|
|
||||||
/// enterStackFrame - Let the StoreManager to do something when execution
|
/// enterStackFrame - Let the StoreManager to do something when execution
|
||||||
/// engine is about to execute into a callee.
|
/// engine is about to execute into a callee.
|
||||||
virtual StoreRef enterStackFrame(const ProgramState *state,
|
virtual StoreRef enterStackFrame(ProgramStateRef state,
|
||||||
const LocationContext *callerCtx,
|
const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx);
|
const StackFrameContext *calleeCtx);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ class SubEngine {
|
||||||
public:
|
public:
|
||||||
virtual ~SubEngine() {}
|
virtual ~SubEngine() {}
|
||||||
|
|
||||||
virtual const ProgramState *getInitialState(const LocationContext *InitLoc) = 0;
|
virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
|
||||||
|
|
||||||
virtual AnalysisManager &getAnalysisManager() = 0;
|
virtual AnalysisManager &getAnalysisManager() = 0;
|
||||||
|
|
||||||
|
@ -90,30 +90,30 @@ public:
|
||||||
|
|
||||||
/// Called by ConstraintManager. Used to call checker-specific
|
/// Called by ConstraintManager. Used to call checker-specific
|
||||||
/// logic for handling assumptions on symbolic values.
|
/// logic for handling assumptions on symbolic values.
|
||||||
virtual const ProgramState *processAssume(const ProgramState *state,
|
virtual ProgramStateRef processAssume(ProgramStateRef state,
|
||||||
SVal cond, bool assumption) = 0;
|
SVal cond, bool assumption) = 0;
|
||||||
|
|
||||||
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
|
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
|
||||||
/// region change should trigger a processRegionChanges update.
|
/// region change should trigger a processRegionChanges update.
|
||||||
virtual bool wantsRegionChangeUpdate(const ProgramState *state) = 0;
|
virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
|
||||||
|
|
||||||
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
|
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
|
||||||
/// to the store. Used to update checkers that track region values.
|
/// to the store. Used to update checkers that track region values.
|
||||||
virtual const ProgramState *
|
virtual ProgramStateRef
|
||||||
processRegionChanges(const ProgramState *state,
|
processRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) = 0;
|
ArrayRef<const MemRegion *> Regions) = 0;
|
||||||
|
|
||||||
|
|
||||||
inline const ProgramState *
|
inline ProgramStateRef
|
||||||
processRegionChange(const ProgramState *state,
|
processRegionChange(ProgramStateRef state,
|
||||||
const MemRegion* MR) {
|
const MemRegion* MR) {
|
||||||
return processRegionChanges(state, 0, MR, MR);
|
return processRegionChanges(state, 0, MR, MR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// printState - Called by ProgramStateManager to print checker-specific data.
|
/// printState - Called by ProgramStateManager to print checker-specific data.
|
||||||
virtual void printState(raw_ostream &Out, const ProgramState *State,
|
virtual void printState(raw_ostream &Out, ProgramStateRef State,
|
||||||
const char *NL, const char *Sep) = 0;
|
const char *NL, const char *Sep) = 0;
|
||||||
|
|
||||||
/// Called by CoreEngine when the analysis worklist is either empty or the
|
/// Called by CoreEngine when the analysis worklist is either empty or the
|
||||||
|
|
|
@ -37,7 +37,7 @@ void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
|
||||||
QualType expectedResultTy = CE->getType();
|
QualType expectedResultTy = CE->getType();
|
||||||
|
|
||||||
// Fetch the signature of the called function.
|
// Fetch the signature of the called function.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
SVal V = state->getSVal(CE, LCtx);
|
SVal V = state->getSVal(CE, LCtx);
|
||||||
|
|
|
@ -51,15 +51,15 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
|
||||||
if (Idx.isZeroConstant())
|
if (Idx.isZeroConstant())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
// Get the size of the array.
|
// Get the size of the array.
|
||||||
DefinedOrUnknownSVal NumElements
|
DefinedOrUnknownSVal NumElements
|
||||||
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
|
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
|
||||||
ER->getValueType());
|
ER->getValueType());
|
||||||
|
|
||||||
const ProgramState *StInBound = state->assumeInBound(Idx, NumElements, true);
|
ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
|
||||||
const ProgramState *StOutBound = state->assumeInBound(Idx, NumElements, false);
|
ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
|
||||||
if (StOutBound && !StInBound) {
|
if (StOutBound && !StInBound) {
|
||||||
ExplodedNode *N = C.generateSink(StOutBound);
|
ExplodedNode *N = C.generateSink(StOutBound);
|
||||||
if (!N)
|
if (!N)
|
||||||
|
|
|
@ -30,7 +30,7 @@ class ArrayBoundCheckerV2 :
|
||||||
|
|
||||||
enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted };
|
enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted };
|
||||||
|
|
||||||
void reportOOB(CheckerContext &C, const ProgramState *errorState,
|
void reportOOB(CheckerContext &C, ProgramStateRef errorState,
|
||||||
OOB_Kind kind) const;
|
OOB_Kind kind) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
NonLoc getByteOffset() const { return cast<NonLoc>(byteOffset); }
|
NonLoc getByteOffset() const { return cast<NonLoc>(byteOffset); }
|
||||||
const SubRegion *getRegion() const { return baseRegion; }
|
const SubRegion *getRegion() const { return baseRegion; }
|
||||||
|
|
||||||
static RegionRawOffsetV2 computeOffset(const ProgramState *state,
|
static RegionRawOffsetV2 computeOffset(ProgramStateRef state,
|
||||||
SValBuilder &svalBuilder,
|
SValBuilder &svalBuilder,
|
||||||
SVal location);
|
SVal location);
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
||||||
// memory access is within the extent of the base region. Since we
|
// memory access is within the extent of the base region. Since we
|
||||||
// have some flexibility in defining the base region, we can achieve
|
// have some flexibility in defining the base region, we can achieve
|
||||||
// various levels of conservatism in our buffer overflow checking.
|
// various levels of conservatism in our buffer overflow checking.
|
||||||
const ProgramState *state = checkerContext.getState();
|
ProgramStateRef state = checkerContext.getState();
|
||||||
const ProgramState *originalState = state;
|
ProgramStateRef originalState = state;
|
||||||
|
|
||||||
SValBuilder &svalBuilder = checkerContext.getSValBuilder();
|
SValBuilder &svalBuilder = checkerContext.getSValBuilder();
|
||||||
const RegionRawOffsetV2 &rawOffset =
|
const RegionRawOffsetV2 &rawOffset =
|
||||||
|
@ -118,7 +118,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
||||||
if (!lowerBoundToCheck)
|
if (!lowerBoundToCheck)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state_precedesLowerBound, *state_withinLowerBound;
|
ProgramStateRef state_precedesLowerBound, state_withinLowerBound;
|
||||||
llvm::tie(state_precedesLowerBound, state_withinLowerBound) =
|
llvm::tie(state_precedesLowerBound, state_withinLowerBound) =
|
||||||
state->assume(*lowerBoundToCheck);
|
state->assume(*lowerBoundToCheck);
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
||||||
if (!upperboundToCheck)
|
if (!upperboundToCheck)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const ProgramState *state_exceedsUpperBound, *state_withinUpperBound;
|
ProgramStateRef state_exceedsUpperBound, state_withinUpperBound;
|
||||||
llvm::tie(state_exceedsUpperBound, state_withinUpperBound) =
|
llvm::tie(state_exceedsUpperBound, state_withinUpperBound) =
|
||||||
state->assume(*upperboundToCheck);
|
state->assume(*upperboundToCheck);
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrayBoundCheckerV2::reportOOB(CheckerContext &checkerContext,
|
void ArrayBoundCheckerV2::reportOOB(CheckerContext &checkerContext,
|
||||||
const ProgramState *errorState,
|
ProgramStateRef errorState,
|
||||||
OOB_Kind kind) const {
|
OOB_Kind kind) const {
|
||||||
|
|
||||||
ExplodedNode *errorNode = checkerContext.generateSink(errorState);
|
ExplodedNode *errorNode = checkerContext.generateSink(errorState);
|
||||||
|
@ -238,7 +238,7 @@ static inline SVal getValue(SVal val, SValBuilder &svalBuilder) {
|
||||||
|
|
||||||
// Scale a base value by a scaling factor, and return the scaled
|
// Scale a base value by a scaling factor, and return the scaled
|
||||||
// value as an SVal. Used by 'computeOffset'.
|
// value as an SVal. Used by 'computeOffset'.
|
||||||
static inline SVal scaleValue(const ProgramState *state,
|
static inline SVal scaleValue(ProgramStateRef state,
|
||||||
NonLoc baseVal, CharUnits scaling,
|
NonLoc baseVal, CharUnits scaling,
|
||||||
SValBuilder &sb) {
|
SValBuilder &sb) {
|
||||||
return sb.evalBinOpNN(state, BO_Mul, baseVal,
|
return sb.evalBinOpNN(state, BO_Mul, baseVal,
|
||||||
|
@ -248,7 +248,7 @@ static inline SVal scaleValue(const ProgramState *state,
|
||||||
|
|
||||||
// Add an SVal to another, treating unknown and undefined values as
|
// Add an SVal to another, treating unknown and undefined values as
|
||||||
// summing to UnknownVal. Used by 'computeOffset'.
|
// summing to UnknownVal. Used by 'computeOffset'.
|
||||||
static SVal addValue(const ProgramState *state, SVal x, SVal y,
|
static SVal addValue(ProgramStateRef state, SVal x, SVal y,
|
||||||
SValBuilder &svalBuilder) {
|
SValBuilder &svalBuilder) {
|
||||||
// We treat UnknownVals and UndefinedVals the same here because we
|
// We treat UnknownVals and UndefinedVals the same here because we
|
||||||
// only care about computing offsets.
|
// only care about computing offsets.
|
||||||
|
@ -262,7 +262,7 @@ static SVal addValue(const ProgramState *state, SVal x, SVal y,
|
||||||
|
|
||||||
/// Compute a raw byte offset from a base region. Used for array bounds
|
/// Compute a raw byte offset from a base region. Used for array bounds
|
||||||
/// checking.
|
/// checking.
|
||||||
RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(const ProgramState *state,
|
RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
|
||||||
SValBuilder &svalBuilder,
|
SValBuilder &svalBuilder,
|
||||||
SVal location)
|
SVal location)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
|
|
||||||
void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
|
void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
// Check if the callee has a 'nonnull' attribute.
|
// Check if the callee has a 'nonnull' attribute.
|
||||||
|
@ -86,7 +86,7 @@ void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintManager &CM = C.getConstraintManager();
|
ConstraintManager &CM = C.getConstraintManager();
|
||||||
const ProgramState *stateNotNull, *stateNull;
|
ProgramStateRef stateNotNull, stateNull;
|
||||||
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
|
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
|
||||||
|
|
||||||
if (stateNull && !stateNotNull) {
|
if (stateNull && !stateNotNull) {
|
||||||
|
|
|
@ -249,7 +249,7 @@ static const char* GetCFNumberTypeStr(uint64_t i) {
|
||||||
|
|
||||||
void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
|
void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
||||||
if (!FD)
|
if (!FD)
|
||||||
return;
|
return;
|
||||||
|
@ -361,7 +361,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
|
||||||
if (CE->getNumArgs() != 1)
|
if (CE->getNumArgs() != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
||||||
if (!FD)
|
if (!FD)
|
||||||
return;
|
return;
|
||||||
|
@ -396,7 +396,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
|
||||||
DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal);
|
DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal);
|
||||||
|
|
||||||
// Are they equal?
|
// Are they equal?
|
||||||
const ProgramState *stateTrue, *stateFalse;
|
ProgramStateRef stateTrue, stateFalse;
|
||||||
llvm::tie(stateTrue, stateFalse) = state->assume(ArgIsNull);
|
llvm::tie(stateTrue, stateFalse) = state->assume(ArgIsNull);
|
||||||
|
|
||||||
if (stateTrue && !stateFalse) {
|
if (stateTrue && !stateFalse) {
|
||||||
|
@ -582,7 +582,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
|
||||||
|
|
||||||
// Verify that all arguments have Objective-C types.
|
// Verify that all arguments have Objective-C types.
|
||||||
llvm::Optional<ExplodedNode*> errorNode;
|
llvm::Optional<ExplodedNode*> errorNode;
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
|
for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
|
||||||
QualType ArgTy = msg.getArgType(I);
|
QualType ArgTy = msg.getArgType(I);
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
|
|
||||||
bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
|
bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
if (!FD)
|
if (!FD)
|
||||||
|
|
|
@ -40,12 +40,12 @@ public:
|
||||||
|
|
||||||
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
|
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
|
||||||
void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
|
void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
|
||||||
void checkLiveSymbols(const ProgramState *state, SymbolReaper &SR) const;
|
void checkLiveSymbols(ProgramStateRef state, SymbolReaper &SR) const;
|
||||||
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
|
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
|
||||||
bool wantsRegionChangeUpdate(const ProgramState *state) const;
|
bool wantsRegionChangeUpdate(ProgramStateRef state) const;
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
checkRegionChanges(const ProgramState *state,
|
checkRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *,
|
const StoreManager::InvalidatedSymbols *,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) const;
|
ArrayRef<const MemRegion *> Regions) const;
|
||||||
|
@ -58,7 +58,7 @@ public:
|
||||||
void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
|
void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
|
||||||
void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
|
void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
|
||||||
void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
|
void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *Source,
|
const Expr *Source,
|
||||||
const Expr *Dest,
|
const Expr *Dest,
|
||||||
|
@ -95,48 +95,48 @@ public:
|
||||||
bool ignoreCase = false) const;
|
bool ignoreCase = false) const;
|
||||||
|
|
||||||
// Utility methods
|
// Utility methods
|
||||||
std::pair<const ProgramState*, const ProgramState*>
|
std::pair<ProgramStateRef , ProgramStateRef >
|
||||||
static assumeZero(CheckerContext &C,
|
static assumeZero(CheckerContext &C,
|
||||||
const ProgramState *state, SVal V, QualType Ty);
|
ProgramStateRef state, SVal V, QualType Ty);
|
||||||
|
|
||||||
static const ProgramState *setCStringLength(const ProgramState *state,
|
static ProgramStateRef setCStringLength(ProgramStateRef state,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
SVal strLength);
|
SVal strLength);
|
||||||
static SVal getCStringLengthForRegion(CheckerContext &C,
|
static SVal getCStringLengthForRegion(CheckerContext &C,
|
||||||
const ProgramState *&state,
|
ProgramStateRef &state,
|
||||||
const Expr *Ex,
|
const Expr *Ex,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
bool hypothetical);
|
bool hypothetical);
|
||||||
SVal getCStringLength(CheckerContext &C,
|
SVal getCStringLength(CheckerContext &C,
|
||||||
const ProgramState *&state,
|
ProgramStateRef &state,
|
||||||
const Expr *Ex,
|
const Expr *Ex,
|
||||||
SVal Buf,
|
SVal Buf,
|
||||||
bool hypothetical = false) const;
|
bool hypothetical = false) const;
|
||||||
|
|
||||||
const StringLiteral *getCStringLiteral(CheckerContext &C,
|
const StringLiteral *getCStringLiteral(CheckerContext &C,
|
||||||
const ProgramState *&state,
|
ProgramStateRef &state,
|
||||||
const Expr *expr,
|
const Expr *expr,
|
||||||
SVal val) const;
|
SVal val) const;
|
||||||
|
|
||||||
static const ProgramState *InvalidateBuffer(CheckerContext &C,
|
static ProgramStateRef InvalidateBuffer(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Ex, SVal V);
|
const Expr *Ex, SVal V);
|
||||||
|
|
||||||
static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
|
static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
|
||||||
const MemRegion *MR);
|
const MemRegion *MR);
|
||||||
|
|
||||||
// Re-usable checks
|
// Re-usable checks
|
||||||
const ProgramState *checkNonNull(CheckerContext &C,
|
ProgramStateRef checkNonNull(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *S,
|
const Expr *S,
|
||||||
SVal l) const;
|
SVal l) const;
|
||||||
const ProgramState *CheckLocation(CheckerContext &C,
|
ProgramStateRef CheckLocation(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *S,
|
const Expr *S,
|
||||||
SVal l,
|
SVal l,
|
||||||
const char *message = NULL) const;
|
const char *message = NULL) const;
|
||||||
const ProgramState *CheckBufferAccess(CheckerContext &C,
|
ProgramStateRef CheckBufferAccess(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *FirstBuf,
|
const Expr *FirstBuf,
|
||||||
const Expr *SecondBuf,
|
const Expr *SecondBuf,
|
||||||
|
@ -144,8 +144,8 @@ public:
|
||||||
const char *secondMessage = NULL,
|
const char *secondMessage = NULL,
|
||||||
bool WarnAboutSize = false) const;
|
bool WarnAboutSize = false) const;
|
||||||
|
|
||||||
const ProgramState *CheckBufferAccess(CheckerContext &C,
|
ProgramStateRef CheckBufferAccess(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *Buf,
|
const Expr *Buf,
|
||||||
const char *message = NULL,
|
const char *message = NULL,
|
||||||
|
@ -154,18 +154,18 @@ public:
|
||||||
return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
|
return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
|
||||||
WarnAboutSize);
|
WarnAboutSize);
|
||||||
}
|
}
|
||||||
const ProgramState *CheckOverlap(CheckerContext &C,
|
ProgramStateRef CheckOverlap(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *First,
|
const Expr *First,
|
||||||
const Expr *Second) const;
|
const Expr *Second) const;
|
||||||
void emitOverlapBug(CheckerContext &C,
|
void emitOverlapBug(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Stmt *First,
|
const Stmt *First,
|
||||||
const Stmt *Second) const;
|
const Stmt *Second) const;
|
||||||
|
|
||||||
const ProgramState *checkAdditionOverflow(CheckerContext &C,
|
ProgramStateRef checkAdditionOverflow(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
NonLoc left,
|
NonLoc left,
|
||||||
NonLoc right) const;
|
NonLoc right) const;
|
||||||
};
|
};
|
||||||
|
@ -190,26 +190,26 @@ namespace ento {
|
||||||
// Individual checks and utility methods.
|
// Individual checks and utility methods.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
std::pair<const ProgramState*, const ProgramState*>
|
std::pair<ProgramStateRef , ProgramStateRef >
|
||||||
CStringChecker::assumeZero(CheckerContext &C, const ProgramState *state, SVal V,
|
CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V,
|
||||||
QualType Ty) {
|
QualType Ty) {
|
||||||
DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
|
DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
|
||||||
if (!val)
|
if (!val)
|
||||||
return std::pair<const ProgramState*, const ProgramState *>(state, state);
|
return std::pair<ProgramStateRef , ProgramStateRef >(state, state);
|
||||||
|
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
|
DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
|
||||||
return state->assume(svalBuilder.evalEQ(state, *val, zero));
|
return state->assume(svalBuilder.evalEQ(state, *val, zero));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::checkNonNull(CheckerContext &C,
|
ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *S, SVal l) const {
|
const Expr *S, SVal l) const {
|
||||||
// If a previous check has failed, propagate the failure.
|
// If a previous check has failed, propagate the failure.
|
||||||
if (!state)
|
if (!state)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const ProgramState *stateNull, *stateNonNull;
|
ProgramStateRef stateNull, stateNonNull;
|
||||||
llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
|
llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
|
||||||
|
|
||||||
if (stateNull && !stateNonNull) {
|
if (stateNull && !stateNonNull) {
|
||||||
|
@ -242,8 +242,8 @@ const ProgramState *CStringChecker::checkNonNull(CheckerContext &C,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
|
// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
|
||||||
const ProgramState *CStringChecker::CheckLocation(CheckerContext &C,
|
ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *S, SVal l,
|
const Expr *S, SVal l,
|
||||||
const char *warningMsg) const {
|
const char *warningMsg) const {
|
||||||
// If a previous check has failed, propagate the failure.
|
// If a previous check has failed, propagate the failure.
|
||||||
|
@ -272,8 +272,8 @@ const ProgramState *CStringChecker::CheckLocation(CheckerContext &C,
|
||||||
// Get the index of the accessed element.
|
// Get the index of the accessed element.
|
||||||
DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
|
DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
|
||||||
|
|
||||||
const ProgramState *StInBound = state->assumeInBound(Idx, Size, true);
|
ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
|
||||||
const ProgramState *StOutBound = state->assumeInBound(Idx, Size, false);
|
ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
|
||||||
if (StOutBound && !StInBound) {
|
if (StOutBound && !StInBound) {
|
||||||
ExplodedNode *N = C.generateSink(StOutBound);
|
ExplodedNode *N = C.generateSink(StOutBound);
|
||||||
if (!N)
|
if (!N)
|
||||||
|
@ -315,8 +315,8 @@ const ProgramState *CStringChecker::CheckLocation(CheckerContext &C,
|
||||||
return StInBound;
|
return StInBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
|
ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *FirstBuf,
|
const Expr *FirstBuf,
|
||||||
const Expr *SecondBuf,
|
const Expr *SecondBuf,
|
||||||
|
@ -388,8 +388,8 @@ const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
|
ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size,
|
const Expr *Size,
|
||||||
const Expr *First,
|
const Expr *First,
|
||||||
const Expr *Second) const {
|
const Expr *Second) const {
|
||||||
|
@ -401,7 +401,7 @@ const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
|
||||||
if (!state)
|
if (!state)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const ProgramState *stateTrue, *stateFalse;
|
ProgramStateRef stateTrue, stateFalse;
|
||||||
|
|
||||||
// Get the buffer values and make sure they're known locations.
|
// Get the buffer values and make sure they're known locations.
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
@ -500,7 +500,7 @@ const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
|
||||||
return stateFalse;
|
return stateFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStringChecker::emitOverlapBug(CheckerContext &C, const ProgramState *state,
|
void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state,
|
||||||
const Stmt *First, const Stmt *Second) const {
|
const Stmt *First, const Stmt *Second) const {
|
||||||
ExplodedNode *N = C.generateSink(state);
|
ExplodedNode *N = C.generateSink(state);
|
||||||
if (!N)
|
if (!N)
|
||||||
|
@ -519,8 +519,8 @@ void CStringChecker::emitOverlapBug(CheckerContext &C, const ProgramState *state
|
||||||
C.EmitReport(report);
|
C.EmitReport(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::checkAdditionOverflow(CheckerContext &C,
|
ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
NonLoc left,
|
NonLoc left,
|
||||||
NonLoc right) const {
|
NonLoc right) const {
|
||||||
// If a previous check has failed, propagate the failure.
|
// If a previous check has failed, propagate the failure.
|
||||||
|
@ -552,7 +552,7 @@ const ProgramState *CStringChecker::checkAdditionOverflow(CheckerContext &C,
|
||||||
SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
|
SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
|
||||||
*maxMinusRightNL, cmpTy);
|
*maxMinusRightNL, cmpTy);
|
||||||
|
|
||||||
const ProgramState *stateOverflow, *stateOkay;
|
ProgramStateRef stateOverflow, stateOkay;
|
||||||
llvm::tie(stateOverflow, stateOkay) =
|
llvm::tie(stateOverflow, stateOkay) =
|
||||||
state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
|
state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
|
||||||
|
|
||||||
|
@ -588,7 +588,7 @@ const ProgramState *CStringChecker::checkAdditionOverflow(CheckerContext &C,
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::setCStringLength(const ProgramState *state,
|
ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
SVal strLength) {
|
SVal strLength) {
|
||||||
assert(!strLength.isUndef() && "Attempt to set an undefined string length");
|
assert(!strLength.isUndef() && "Attempt to set an undefined string length");
|
||||||
|
@ -629,7 +629,7 @@ const ProgramState *CStringChecker::setCStringLength(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
|
SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
|
||||||
const ProgramState *&state,
|
ProgramStateRef &state,
|
||||||
const Expr *Ex,
|
const Expr *Ex,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
bool hypothetical) {
|
bool hypothetical) {
|
||||||
|
@ -653,7 +653,7 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
|
||||||
return strLength;
|
return strLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&state,
|
SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
|
||||||
const Expr *Ex, SVal Buf,
|
const Expr *Ex, SVal Buf,
|
||||||
bool hypothetical) const {
|
bool hypothetical) const {
|
||||||
const MemRegion *MR = Buf.getAsRegion();
|
const MemRegion *MR = Buf.getAsRegion();
|
||||||
|
@ -748,7 +748,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&st
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
|
const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
|
||||||
const ProgramState *&state, const Expr *expr, SVal val) const {
|
ProgramStateRef &state, const Expr *expr, SVal val) const {
|
||||||
|
|
||||||
// Get the memory region pointed to by the val.
|
// Get the memory region pointed to by the val.
|
||||||
const MemRegion *bufRegion = val.getAsRegion();
|
const MemRegion *bufRegion = val.getAsRegion();
|
||||||
|
@ -767,8 +767,8 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
|
||||||
return strRegion->getStringLiteral();
|
return strRegion->getStringLiteral();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *CStringChecker::InvalidateBuffer(CheckerContext &C,
|
ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *E, SVal V) {
|
const Expr *E, SVal V) {
|
||||||
Loc *L = dyn_cast<Loc>(&V);
|
Loc *L = dyn_cast<Loc>(&V);
|
||||||
if (!L)
|
if (!L)
|
||||||
|
@ -841,7 +841,7 @@ bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
|
||||||
|
|
||||||
void CStringChecker::evalCopyCommon(CheckerContext &C,
|
void CStringChecker::evalCopyCommon(CheckerContext &C,
|
||||||
const CallExpr *CE,
|
const CallExpr *CE,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Expr *Size, const Expr *Dest,
|
const Expr *Size, const Expr *Dest,
|
||||||
const Expr *Source, bool Restricted,
|
const Expr *Source, bool Restricted,
|
||||||
bool IsMempcpy) const {
|
bool IsMempcpy) const {
|
||||||
|
@ -852,7 +852,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
|
||||||
SVal sizeVal = state->getSVal(Size, LCtx);
|
SVal sizeVal = state->getSVal(Size, LCtx);
|
||||||
QualType sizeTy = Size->getType();
|
QualType sizeTy = Size->getType();
|
||||||
|
|
||||||
const ProgramState *stateZeroSize, *stateNonZeroSize;
|
ProgramStateRef stateZeroSize, stateNonZeroSize;
|
||||||
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
||||||
assumeZero(C, state, sizeVal, sizeTy);
|
assumeZero(C, state, sizeVal, sizeTy);
|
||||||
|
|
||||||
|
@ -945,7 +945,7 @@ void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
|
||||||
// void *memcpy(void *restrict dst, const void *restrict src, size_t n);
|
// void *memcpy(void *restrict dst, const void *restrict src, size_t n);
|
||||||
// The return value is the address of the destination buffer.
|
// The return value is the address of the destination buffer.
|
||||||
const Expr *Dest = CE->getArg(0);
|
const Expr *Dest = CE->getArg(0);
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
|
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
|
||||||
}
|
}
|
||||||
|
@ -954,7 +954,7 @@ void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
|
||||||
// void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
|
// void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
|
||||||
// The return value is a pointer to the byte following the last written byte.
|
// The return value is a pointer to the byte following the last written byte.
|
||||||
const Expr *Dest = CE->getArg(0);
|
const Expr *Dest = CE->getArg(0);
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
|
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
|
||||||
}
|
}
|
||||||
|
@ -963,7 +963,7 @@ void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
|
||||||
// void *memmove(void *dst, const void *src, size_t n);
|
// void *memmove(void *dst, const void *src, size_t n);
|
||||||
// The return value is the address of the destination buffer.
|
// The return value is the address of the destination buffer.
|
||||||
const Expr *Dest = CE->getArg(0);
|
const Expr *Dest = CE->getArg(0);
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
|
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const Expr *Right = CE->getArg(1);
|
const Expr *Right = CE->getArg(1);
|
||||||
const Expr *Size = CE->getArg(2);
|
const Expr *Size = CE->getArg(2);
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
|
|
||||||
// See if the size argument is zero.
|
// See if the size argument is zero.
|
||||||
|
@ -990,7 +990,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
||||||
SVal sizeVal = state->getSVal(Size, LCtx);
|
SVal sizeVal = state->getSVal(Size, LCtx);
|
||||||
QualType sizeTy = Size->getType();
|
QualType sizeTy = Size->getType();
|
||||||
|
|
||||||
const ProgramState *stateZeroSize, *stateNonZeroSize;
|
ProgramStateRef stateZeroSize, stateNonZeroSize;
|
||||||
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
||||||
assumeZero(C, state, sizeVal, sizeTy);
|
assumeZero(C, state, sizeVal, sizeTy);
|
||||||
|
|
||||||
|
@ -1016,7 +1016,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
||||||
|
|
||||||
// See if they are the same.
|
// See if they are the same.
|
||||||
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
|
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
|
||||||
const ProgramState *StSameBuf, *StNotSameBuf;
|
ProgramStateRef StSameBuf, StNotSameBuf;
|
||||||
llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
|
llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
|
||||||
|
|
||||||
// If the two arguments might be the same buffer, we know the result is 0,
|
// If the two arguments might be the same buffer, we know the result is 0,
|
||||||
|
@ -1062,14 +1062,14 @@ void CStringChecker::evalstrnLength(CheckerContext &C,
|
||||||
void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
|
void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
bool IsStrnlen) const {
|
bool IsStrnlen) const {
|
||||||
CurrentFunctionDescription = "string length function";
|
CurrentFunctionDescription = "string length function";
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
if (IsStrnlen) {
|
if (IsStrnlen) {
|
||||||
const Expr *maxlenExpr = CE->getArg(1);
|
const Expr *maxlenExpr = CE->getArg(1);
|
||||||
SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
|
SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
|
||||||
|
|
||||||
const ProgramState *stateZeroSize, *stateNonZeroSize;
|
ProgramStateRef stateZeroSize, stateNonZeroSize;
|
||||||
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
llvm::tie(stateZeroSize, stateNonZeroSize) =
|
||||||
assumeZero(C, state, maxlenVal, maxlenExpr->getType());
|
assumeZero(C, state, maxlenVal, maxlenExpr->getType());
|
||||||
|
|
||||||
|
@ -1121,7 +1121,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
|
NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
|
||||||
|
|
||||||
if (strLengthNL && maxlenValNL) {
|
if (strLengthNL && maxlenValNL) {
|
||||||
const ProgramState *stateStringTooLong, *stateStringNotTooLong;
|
ProgramStateRef stateStringTooLong, stateStringNotTooLong;
|
||||||
|
|
||||||
// Check if the strLength is greater than the maxlen.
|
// Check if the strLength is greater than the maxlen.
|
||||||
llvm::tie(stateStringTooLong, stateStringNotTooLong) =
|
llvm::tie(stateStringTooLong, stateStringNotTooLong) =
|
||||||
|
@ -1228,7 +1228,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
bool returnEnd, bool isBounded,
|
bool returnEnd, bool isBounded,
|
||||||
bool isAppending) const {
|
bool isAppending) const {
|
||||||
CurrentFunctionDescription = "string copy function";
|
CurrentFunctionDescription = "string copy function";
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
// Check that the destination is non-null.
|
// Check that the destination is non-null.
|
||||||
|
@ -1279,7 +1279,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
// If we know both values, we might be able to figure out how much
|
// If we know both values, we might be able to figure out how much
|
||||||
// we're copying.
|
// we're copying.
|
||||||
if (strLengthNL && lenValNL) {
|
if (strLengthNL && lenValNL) {
|
||||||
const ProgramState *stateSourceTooLong, *stateSourceNotTooLong;
|
ProgramStateRef stateSourceTooLong, stateSourceNotTooLong;
|
||||||
|
|
||||||
// Check if the max number to copy is less than the length of the src.
|
// Check if the max number to copy is less than the length of the src.
|
||||||
// If the bound is equal to the source length, strncpy won't null-
|
// If the bound is equal to the source length, strncpy won't null-
|
||||||
|
@ -1552,7 +1552,7 @@ void CStringChecker::evalStrncasecmp(CheckerContext &C,
|
||||||
void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
bool isBounded, bool ignoreCase) const {
|
bool isBounded, bool ignoreCase) const {
|
||||||
CurrentFunctionDescription = "string comparison function";
|
CurrentFunctionDescription = "string comparison function";
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
// Check that the first string is non-null
|
// Check that the first string is non-null
|
||||||
|
@ -1588,7 +1588,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
||||||
// See if they are the same.
|
// See if they are the same.
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
|
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
|
||||||
const ProgramState *StSameBuf, *StNotSameBuf;
|
ProgramStateRef StSameBuf, StNotSameBuf;
|
||||||
llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
|
llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
|
||||||
|
|
||||||
// If the two arguments might be the same buffer, we know the result is 0,
|
// If the two arguments might be the same buffer, we know the result is 0,
|
||||||
|
@ -1718,7 +1718,7 @@ bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
||||||
|
|
||||||
void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
||||||
// Record string length for char a[] = "abc";
|
// Record string length for char a[] = "abc";
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
|
for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
|
@ -1752,13 +1752,13 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStringChecker::wantsRegionChangeUpdate(const ProgramState *state) const {
|
bool CStringChecker::wantsRegionChangeUpdate(ProgramStateRef state) const {
|
||||||
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
||||||
return !Entries.isEmpty();
|
return !Entries.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
CStringChecker::checkRegionChanges(const ProgramState *state,
|
CStringChecker::checkRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *,
|
const StoreManager::InvalidatedSymbols *,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) const {
|
ArrayRef<const MemRegion *> Regions) const {
|
||||||
|
@ -1809,7 +1809,7 @@ CStringChecker::checkRegionChanges(const ProgramState *state,
|
||||||
return state->set<CStringLength>(Entries);
|
return state->set<CStringLength>(Entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStringChecker::checkLiveSymbols(const ProgramState *state,
|
void CStringChecker::checkLiveSymbols(ProgramStateRef state,
|
||||||
SymbolReaper &SR) const {
|
SymbolReaper &SR) const {
|
||||||
// Mark all symbols in our string length map as valid.
|
// Mark all symbols in our string length map as valid.
|
||||||
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
||||||
|
@ -1829,7 +1829,7 @@ void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
|
||||||
if (!SR.hasDeadSymbols())
|
if (!SR.hasDeadSymbols())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
CStringLength::EntryMap Entries = state->get<CStringLength>();
|
||||||
if (Entries.isEmpty())
|
if (Entries.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -49,7 +49,7 @@ private:
|
||||||
ExplodedNode *N) const;
|
ExplodedNode *N) const;
|
||||||
|
|
||||||
void HandleNilReceiver(CheckerContext &C,
|
void HandleNilReceiver(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
ObjCMessage msg) const;
|
ObjCMessage msg) const;
|
||||||
|
|
||||||
static void LazyInit_BT(const char *desc, llvm::OwningPtr<BugType> &BT) {
|
static void LazyInit_BT(const char *desc, llvm::OwningPtr<BugType> &BT) {
|
||||||
|
@ -219,7 +219,7 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
|
||||||
void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
|
void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
|
|
||||||
// FIXME: Handle 'super'?
|
// FIXME: Handle 'super'?
|
||||||
|
@ -242,7 +242,7 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
|
||||||
// Bifurcate the state into nil and non-nil ones.
|
// Bifurcate the state into nil and non-nil ones.
|
||||||
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
|
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
|
||||||
|
|
||||||
const ProgramState *notNilState, *nilState;
|
ProgramStateRef notNilState, nilState;
|
||||||
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
|
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
|
||||||
|
|
||||||
// Handle receiver must be nil.
|
// Handle receiver must be nil.
|
||||||
|
@ -293,7 +293,7 @@ static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
ObjCMessage msg) const {
|
ObjCMessage msg) const {
|
||||||
ASTContext &Ctx = C.getASTContext();
|
ASTContext &Ctx = C.getASTContext();
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
|
||||||
if (ToPointeeTy->isIncompleteType())
|
if (ToPointeeTy->isIncompleteType())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const MemRegion *R = state->getSVal(E, C.getLocationContext()).getAsRegion();
|
const MemRegion *R = state->getSVal(E, C.getLocationContext()).getAsRegion();
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -173,7 +173,7 @@ public:
|
||||||
/// performed on the symbols of interest and change the state accordingly.
|
/// performed on the symbols of interest and change the state accordingly.
|
||||||
///
|
///
|
||||||
/// eval::Assume
|
/// eval::Assume
|
||||||
const ProgramState *evalAssume(const ProgramState *State,
|
ProgramStateRef evalAssume(ProgramStateRef State,
|
||||||
SVal Cond,
|
SVal Cond,
|
||||||
bool Assumption) const { return State; }
|
bool Assumption) const { return State; }
|
||||||
|
|
||||||
|
@ -182,12 +182,12 @@ public:
|
||||||
/// dead and removed.
|
/// dead and removed.
|
||||||
///
|
///
|
||||||
/// check::LiveSymbols
|
/// check::LiveSymbols
|
||||||
void checkLiveSymbols(const ProgramState *State, SymbolReaper &SR) const {}
|
void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
|
||||||
|
|
||||||
/// check::RegionChanges
|
/// check::RegionChanges
|
||||||
bool wantsRegionChangeUpdate(const ProgramState *St) const { return true; }
|
bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
checkRegionChanges(const ProgramState *State,
|
checkRegionChanges(ProgramStateRef State,
|
||||||
const StoreManager::InvalidatedSymbols *,
|
const StoreManager::InvalidatedSymbols *,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) const {
|
ArrayRef<const MemRegion *> Regions) const {
|
||||||
|
|
|
@ -85,7 +85,7 @@ bool ChrootChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
|
void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
ProgramStateManager &Mgr = state->getStateManager();
|
ProgramStateManager &Mgr = state->getStateManager();
|
||||||
|
|
||||||
// Once encouter a chroot(), set the enum value ROOT_CHANGED directly in
|
// Once encouter a chroot(), set the enum value ROOT_CHANGED directly in
|
||||||
|
@ -95,7 +95,7 @@ void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
|
void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
ProgramStateManager &Mgr = state->getStateManager();
|
ProgramStateManager &Mgr = state->getStateManager();
|
||||||
|
|
||||||
// If there are no jail state in the GDM, just return.
|
// If there are no jail state in the GDM, just return.
|
||||||
|
|
|
@ -89,8 +89,8 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
|
||||||
if (!isa<Loc>(location))
|
if (!isa<Loc>(location))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const ProgramState *notNullState, *nullState;
|
ProgramStateRef notNullState, nullState;
|
||||||
llvm::tie(notNullState, nullState) = state->assume(location);
|
llvm::tie(notNullState, nullState) = state->assume(location);
|
||||||
|
|
||||||
// The explicit NULL case.
|
// The explicit NULL case.
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace {
|
||||||
class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
|
class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
|
||||||
mutable llvm::OwningPtr<BuiltinBug> BT;
|
mutable llvm::OwningPtr<BuiltinBug> BT;
|
||||||
void reportBug(const char *Msg,
|
void reportBug(const char *Msg,
|
||||||
const ProgramState *StateZero,
|
ProgramStateRef StateZero,
|
||||||
CheckerContext &C) const ;
|
CheckerContext &C) const ;
|
||||||
public:
|
public:
|
||||||
void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
|
void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
void DivZeroChecker::reportBug(const char *Msg,
|
void DivZeroChecker::reportBug(const char *Msg,
|
||||||
const ProgramState *StateZero,
|
ProgramStateRef StateZero,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
if (ExplodedNode *N = C.generateSink(StateZero)) {
|
if (ExplodedNode *N = C.generateSink(StateZero)) {
|
||||||
if (!BT)
|
if (!BT)
|
||||||
|
@ -72,7 +72,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
|
||||||
|
|
||||||
// Check for divide by zero.
|
// Check for divide by zero.
|
||||||
ConstraintManager &CM = C.getConstraintManager();
|
ConstraintManager &CM = C.getConstraintManager();
|
||||||
const ProgramState *stateNotZero, *stateZero;
|
ProgramStateRef stateNotZero, stateZero;
|
||||||
llvm::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
|
llvm::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
|
||||||
|
|
||||||
if (!stateNotZero) {
|
if (!stateNotZero) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
|
||||||
if (!T->isPointerType())
|
if (!T->isPointerType())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SVal RV = state->getSVal(B->getRHS(), C.getLocationContext());
|
SVal RV = state->getSVal(B->getRHS(), C.getLocationContext());
|
||||||
|
|
||||||
if (!RV.isConstant() || RV.isZeroConstant())
|
if (!RV.isConstant() || RV.isZeroConstant())
|
||||||
|
|
|
@ -70,14 +70,14 @@ private:
|
||||||
static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg);
|
static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg);
|
||||||
|
|
||||||
/// Functions defining the attack surface.
|
/// Functions defining the attack surface.
|
||||||
typedef const ProgramState *(GenericTaintChecker::*FnCheck)(const CallExpr *,
|
typedef ProgramStateRef (GenericTaintChecker::*FnCheck)(const CallExpr *,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
const ProgramState *postScanf(const CallExpr *CE, CheckerContext &C) const;
|
ProgramStateRef postScanf(const CallExpr *CE, CheckerContext &C) const;
|
||||||
const ProgramState *postSocket(const CallExpr *CE, CheckerContext &C) const;
|
ProgramStateRef postSocket(const CallExpr *CE, CheckerContext &C) const;
|
||||||
const ProgramState *postRetTaint(const CallExpr *CE, CheckerContext &C) const;
|
ProgramStateRef postRetTaint(const CallExpr *CE, CheckerContext &C) const;
|
||||||
|
|
||||||
/// Taint the scanned input if the file is tainted.
|
/// Taint the scanned input if the file is tainted.
|
||||||
const ProgramState *preFscanf(const CallExpr *CE, CheckerContext &C) const;
|
ProgramStateRef preFscanf(const CallExpr *CE, CheckerContext &C) const;
|
||||||
|
|
||||||
/// Check for CWE-134: Uncontrolled Format String.
|
/// Check for CWE-134: Uncontrolled Format String.
|
||||||
static const char MsgUncontrolledFormatString[];
|
static const char MsgUncontrolledFormatString[];
|
||||||
|
@ -156,7 +156,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isTaintedOrPointsToTainted(const Expr *E,
|
static inline bool isTaintedOrPointsToTainted(const Expr *E,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
CheckerContext &C) {
|
CheckerContext &C) {
|
||||||
return (State->isTainted(E, C.getLocationContext()) || isStdin(E, C) ||
|
return (State->isTainted(E, C.getLocationContext()) || isStdin(E, C) ||
|
||||||
(E->getType().getTypePtr()->isPointerType() &&
|
(E->getType().getTypePtr()->isPointerType() &&
|
||||||
|
@ -165,7 +165,7 @@ private:
|
||||||
|
|
||||||
/// \brief Pre-process a function which propagates taint according to the
|
/// \brief Pre-process a function which propagates taint according to the
|
||||||
/// taint rule.
|
/// taint rule.
|
||||||
const ProgramState *process(const CallExpr *CE, CheckerContext &C) const;
|
ProgramStateRef process(const CallExpr *CE, CheckerContext &C) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -296,7 +296,7 @@ void GenericTaintChecker::checkPostStmt(const CallExpr *CE,
|
||||||
|
|
||||||
void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
|
void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = 0;
|
ProgramStateRef State = 0;
|
||||||
const FunctionDecl *FDecl = C.getCalleeDecl(CE);
|
const FunctionDecl *FDecl = C.getCalleeDecl(CE);
|
||||||
StringRef Name = C.getCalleeName(FDecl);
|
StringRef Name = C.getCalleeName(FDecl);
|
||||||
if (Name.empty())
|
if (Name.empty())
|
||||||
|
@ -328,7 +328,7 @@ void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
|
||||||
|
|
||||||
bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
|
bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
|
|
||||||
// Depending on what was tainted at pre-visit, we determined a set of
|
// Depending on what was tainted at pre-visit, we determined a set of
|
||||||
// arguments which should be tainted after the function returns. These are
|
// arguments which should be tainted after the function returns. These are
|
||||||
|
@ -388,7 +388,7 @@ void GenericTaintChecker::addSourcesPost(const CallExpr *CE,
|
||||||
|
|
||||||
// If the callee isn't defined, it is not of security concern.
|
// If the callee isn't defined, it is not of security concern.
|
||||||
// Check and evaluate the call.
|
// Check and evaluate the call.
|
||||||
const ProgramState *State = 0;
|
ProgramStateRef State = 0;
|
||||||
if (evalFunction)
|
if (evalFunction)
|
||||||
State = (this->*evalFunction)(CE, C);
|
State = (this->*evalFunction)(CE, C);
|
||||||
if (!State)
|
if (!State)
|
||||||
|
@ -418,7 +418,7 @@ bool GenericTaintChecker::checkPre(const CallExpr *CE, CheckerContext &C) const{
|
||||||
|
|
||||||
SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
|
SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
|
||||||
const Expr* Arg) {
|
const Expr* Arg) {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext());
|
SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext());
|
||||||
if (AddrVal.isUnknownOrUndef())
|
if (AddrVal.isUnknownOrUndef())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -434,10 +434,10 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
|
||||||
return Val.getAsSymbol();
|
return Val.getAsSymbol();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
|
GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
|
|
||||||
// Check for taint in arguments.
|
// Check for taint in arguments.
|
||||||
bool IsTainted = false;
|
bool IsTainted = false;
|
||||||
|
@ -504,10 +504,10 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
|
||||||
|
|
||||||
// If argument 0 (file descriptor) is tainted, all arguments except for arg 0
|
// If argument 0 (file descriptor) is tainted, all arguments except for arg 0
|
||||||
// and arg 1 should get taint.
|
// and arg 1 should get taint.
|
||||||
const ProgramState *GenericTaintChecker::preFscanf(const CallExpr *CE,
|
ProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
assert(CE->getNumArgs() >= 2);
|
assert(CE->getNumArgs() >= 2);
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
|
|
||||||
// Check is the file descriptor is tainted.
|
// Check is the file descriptor is tainted.
|
||||||
if (State->isTainted(CE->getArg(0), C.getLocationContext()) ||
|
if (State->isTainted(CE->getArg(0), C.getLocationContext()) ||
|
||||||
|
@ -523,10 +523,10 @@ const ProgramState *GenericTaintChecker::preFscanf(const CallExpr *CE,
|
||||||
|
|
||||||
|
|
||||||
// If argument 0(protocol domain) is network, the return value should get taint.
|
// If argument 0(protocol domain) is network, the return value should get taint.
|
||||||
const ProgramState *GenericTaintChecker::postSocket(const CallExpr *CE,
|
ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
assert(CE->getNumArgs() >= 3);
|
assert(CE->getNumArgs() >= 3);
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
|
|
||||||
SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
|
SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
|
||||||
StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
|
StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
|
||||||
|
@ -538,9 +538,9 @@ const ProgramState *GenericTaintChecker::postSocket(const CallExpr *CE,
|
||||||
return State;
|
return State;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *GenericTaintChecker::postScanf(const CallExpr *CE,
|
ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
assert(CE->getNumArgs() >= 2);
|
assert(CE->getNumArgs() >= 2);
|
||||||
SVal x = State->getSVal(CE->getArg(1), C.getLocationContext());
|
SVal x = State->getSVal(CE->getArg(1), C.getLocationContext());
|
||||||
// All arguments except for the very first one should get taint.
|
// All arguments except for the very first one should get taint.
|
||||||
|
@ -555,13 +555,13 @@ const ProgramState *GenericTaintChecker::postScanf(const CallExpr *CE,
|
||||||
return State;
|
return State;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *GenericTaintChecker::postRetTaint(const CallExpr *CE,
|
ProgramStateRef GenericTaintChecker::postRetTaint(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
return C.getState()->addTaint(CE, C.getLocationContext());
|
return C.getState()->addTaint(CE, C.getLocationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) {
|
bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
SVal Val = State->getSVal(E, C.getLocationContext());
|
SVal Val = State->getSVal(E, C.getLocationContext());
|
||||||
|
|
||||||
// stdin is a pointer, so it would be a region.
|
// stdin is a pointer, so it would be a region.
|
||||||
|
@ -627,7 +627,7 @@ bool GenericTaintChecker::generateReportIfTainted(const Expr *E,
|
||||||
assert(E);
|
assert(E);
|
||||||
|
|
||||||
// Check for taint.
|
// Check for taint.
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
if (!State->isTainted(getPointedToSymbol(C, E)) &&
|
if (!State->isTainted(getPointedToSymbol(C, E)) &&
|
||||||
!State->isTainted(E, C.getLocationContext()))
|
!State->isTainted(E, C.getLocationContext()))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -141,7 +141,7 @@ void IdempotentOperationChecker::checkPreStmt(const BinaryOperator *B,
|
||||||
|| containsNonLocalVarDecl(RHS);
|
|| containsNonLocalVarDecl(RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
SVal LHSVal = state->getSVal(LHS, LCtx);
|
SVal LHSVal = state->getSVal(LHS, LCtx);
|
||||||
SVal RHSVal = state->getSVal(RHS, LCtx);
|
SVal RHSVal = state->getSVal(RHS, LCtx);
|
||||||
|
|
|
@ -117,17 +117,17 @@ public:
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ProgramState *handleAssign(const ProgramState *state,
|
ProgramStateRef handleAssign(ProgramStateRef state,
|
||||||
const Expr *lexp,
|
const Expr *lexp,
|
||||||
const Expr *rexp,
|
const Expr *rexp,
|
||||||
const LocationContext *LC) const;
|
const LocationContext *LC) const;
|
||||||
|
|
||||||
const ProgramState *handleAssign(const ProgramState *state,
|
ProgramStateRef handleAssign(ProgramStateRef state,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
const Expr *rexp,
|
const Expr *rexp,
|
||||||
const LocationContext *LC) const;
|
const LocationContext *LC) const;
|
||||||
|
|
||||||
const ProgramState *invalidateIterators(const ProgramState *state,
|
ProgramStateRef invalidateIterators(ProgramStateRef state,
|
||||||
const MemRegion *MR,
|
const MemRegion *MR,
|
||||||
const MemberExpr *ME) const;
|
const MemberExpr *ME) const;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ private:
|
||||||
|
|
||||||
void checkArgs(CheckerContext &C, const CallExpr *CE) const;
|
void checkArgs(CheckerContext &C, const CallExpr *CE) const;
|
||||||
|
|
||||||
const MemRegion *getRegion(const ProgramState *state,
|
const MemRegion *getRegion(ProgramStateRef state,
|
||||||
const Expr *E,
|
const Expr *E,
|
||||||
const LocationContext *LC) const;
|
const LocationContext *LC) const;
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ static RefKind getTemplateKind(QualType T) {
|
||||||
|
|
||||||
// Iterate through our map and invalidate any iterators that were
|
// Iterate through our map and invalidate any iterators that were
|
||||||
// initialized fromt the specified instance MemRegion.
|
// initialized fromt the specified instance MemRegion.
|
||||||
const ProgramState *IteratorsChecker::invalidateIterators(const ProgramState *state,
|
ProgramStateRef IteratorsChecker::invalidateIterators(ProgramStateRef state,
|
||||||
const MemRegion *MR, const MemberExpr *ME) const {
|
const MemRegion *MR, const MemberExpr *ME) const {
|
||||||
IteratorState::EntryMap Map = state->get<IteratorState>();
|
IteratorState::EntryMap Map = state->get<IteratorState>();
|
||||||
if (Map.isEmpty())
|
if (Map.isEmpty())
|
||||||
|
@ -246,7 +246,7 @@ const ProgramState *IteratorsChecker::invalidateIterators(const ProgramState *st
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle assigning to an iterator where we don't have the LValue MemRegion.
|
// Handle assigning to an iterator where we don't have the LValue MemRegion.
|
||||||
const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state,
|
ProgramStateRef IteratorsChecker::handleAssign(ProgramStateRef state,
|
||||||
const Expr *lexp, const Expr *rexp, const LocationContext *LC) const {
|
const Expr *lexp, const Expr *rexp, const LocationContext *LC) const {
|
||||||
// Skip the cast if present.
|
// Skip the cast if present.
|
||||||
if (const MaterializeTemporaryExpr *M
|
if (const MaterializeTemporaryExpr *M
|
||||||
|
@ -271,7 +271,7 @@ const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle assigning to an iterator
|
// handle assigning to an iterator
|
||||||
const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state,
|
ProgramStateRef IteratorsChecker::handleAssign(ProgramStateRef state,
|
||||||
const MemRegion *MR, const Expr *rexp, const LocationContext *LC) const {
|
const MemRegion *MR, const Expr *rexp, const LocationContext *LC) const {
|
||||||
// Assume unknown until we find something definite.
|
// Assume unknown until we find something definite.
|
||||||
state = state->set<IteratorState>(MR, RefState::getUnknown());
|
state = state->set<IteratorState>(MR, RefState::getUnknown());
|
||||||
|
@ -376,7 +376,7 @@ const DeclRefExpr *IteratorsChecker::getDeclRefExpr(const Expr *E) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the MemRegion associated with the expresssion.
|
// Get the MemRegion associated with the expresssion.
|
||||||
const MemRegion *IteratorsChecker::getRegion(const ProgramState *state,
|
const MemRegion *IteratorsChecker::getRegion(ProgramStateRef state,
|
||||||
const Expr *E, const LocationContext *LC) const {
|
const Expr *E, const LocationContext *LC) const {
|
||||||
const DeclRefExpr *DRE = getDeclRefExpr(E);
|
const DeclRefExpr *DRE = getDeclRefExpr(E);
|
||||||
if (!DRE)
|
if (!DRE)
|
||||||
|
@ -394,7 +394,7 @@ const MemRegion *IteratorsChecker::getRegion(const ProgramState *state,
|
||||||
// use those nodes. We also cannot create multiple nodes at one ProgramPoint
|
// use those nodes. We also cannot create multiple nodes at one ProgramPoint
|
||||||
// with the same tag.
|
// with the same tag.
|
||||||
void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const {
|
void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const MemRegion *MR = getRegion(state, E, C.getLocationContext());
|
const MemRegion *MR = getRegion(state, E, C.getLocationContext());
|
||||||
if (!MR)
|
if (!MR)
|
||||||
return;
|
return;
|
||||||
|
@ -466,7 +466,7 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE,
|
||||||
CheckerContext &C) const
|
CheckerContext &C) const
|
||||||
{
|
{
|
||||||
const LocationContext *LC = C.getLocationContext();
|
const LocationContext *LC = C.getLocationContext();
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
OverloadedOperatorKind Kind = OCE->getOperator();
|
OverloadedOperatorKind Kind = OCE->getOperator();
|
||||||
if (Kind == OO_Equal) {
|
if (Kind == OO_Equal) {
|
||||||
checkExpr(C, OCE->getArg(1));
|
checkExpr(C, OCE->getArg(1));
|
||||||
|
@ -523,7 +523,7 @@ void IteratorsChecker::checkPreStmt(const DeclStmt *DS,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the MemRegion associated with the iterator and mark it as Undefined.
|
// Get the MemRegion associated with the iterator and mark it as Undefined.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
Loc VarLoc = state->getLValue(VD, C.getLocationContext());
|
Loc VarLoc = state->getLValue(VD, C.getLocationContext());
|
||||||
const MemRegion *MR = VarLoc.getAsRegion();
|
const MemRegion *MR = VarLoc.getAsRegion();
|
||||||
if (!MR)
|
if (!MR)
|
||||||
|
@ -581,7 +581,7 @@ void IteratorsChecker::checkPreStmt(const CXXMemberCallExpr *MCE,
|
||||||
return;
|
return;
|
||||||
// If we are calling a function that invalidates iterators, mark them
|
// If we are calling a function that invalidates iterators, mark them
|
||||||
// appropriately by finding matching instances.
|
// appropriately by finding matching instances.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
StringRef mName = ME->getMemberDecl()->getName();
|
StringRef mName = ME->getMemberDecl()->getName();
|
||||||
if (llvm::StringSwitch<bool>(mName)
|
if (llvm::StringSwitch<bool>(mName)
|
||||||
.Cases("insert", "reserve", "push_back", true)
|
.Cases("insert", "reserve", "push_back", true)
|
||||||
|
|
|
@ -105,13 +105,13 @@ private:
|
||||||
|
|
||||||
/// Check if RetSym evaluates to an error value in the current state.
|
/// Check if RetSym evaluates to an error value in the current state.
|
||||||
bool definitelyReturnedError(SymbolRef RetSym,
|
bool definitelyReturnedError(SymbolRef RetSym,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
SValBuilder &Builder,
|
SValBuilder &Builder,
|
||||||
bool noError = false) const;
|
bool noError = false) const;
|
||||||
|
|
||||||
/// Check if RetSym evaluates to a NoErr value in the current state.
|
/// Check if RetSym evaluates to a NoErr value in the current state.
|
||||||
bool definitelyDidnotReturnError(SymbolRef RetSym,
|
bool definitelyDidnotReturnError(SymbolRef RetSym,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
SValBuilder &Builder) const {
|
SValBuilder &Builder) const {
|
||||||
return definitelyReturnedError(RetSym, State, Builder, true);
|
return definitelyReturnedError(RetSym, State, Builder, true);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ static bool isBadDeallocationArgument(const MemRegion *Arg) {
|
||||||
/// that value is itself an address, and return the corresponding symbol.
|
/// that value is itself an address, and return the corresponding symbol.
|
||||||
static SymbolRef getAsPointeeSymbol(const Expr *Expr,
|
static SymbolRef getAsPointeeSymbol(const Expr *Expr,
|
||||||
CheckerContext &C) {
|
CheckerContext &C) {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
SVal ArgV = State->getSVal(Expr, C.getLocationContext());
|
SVal ArgV = State->getSVal(Expr, C.getLocationContext());
|
||||||
|
|
||||||
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
|
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
|
||||||
|
@ -238,14 +238,14 @@ static SymbolRef getAsPointeeSymbol(const Expr *Expr,
|
||||||
// If noError, returns true iff (1).
|
// If noError, returns true iff (1).
|
||||||
// If !noError, returns true iff (2).
|
// If !noError, returns true iff (2).
|
||||||
bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
|
bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
SValBuilder &Builder,
|
SValBuilder &Builder,
|
||||||
bool noError) const {
|
bool noError) const {
|
||||||
DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
|
DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
|
||||||
Builder.getSymbolManager().getType(RetSym));
|
Builder.getSymbolManager().getType(RetSym));
|
||||||
DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
|
DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
|
||||||
nonloc::SymbolVal(RetSym));
|
nonloc::SymbolVal(RetSym));
|
||||||
const ProgramState *ErrState = State->assume(NoErr, noError);
|
ProgramStateRef ErrState = State->assume(NoErr, noError);
|
||||||
if (ErrState == State) {
|
if (ErrState == State) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,7 @@ void MacOSKeychainAPIChecker::
|
||||||
generateDeallocatorMismatchReport(const AllocationPair &AP,
|
generateDeallocatorMismatchReport(const AllocationPair &AP,
|
||||||
const Expr *ArgExpr,
|
const Expr *ArgExpr,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
State = State->remove<AllocatedData>(AP.first);
|
State = State->remove<AllocatedData>(AP.first);
|
||||||
ExplodedNode *N = C.addTransition(State);
|
ExplodedNode *N = C.addTransition(State);
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ void MacOSKeychainAPIChecker::
|
||||||
void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
unsigned idx = InvalidIdx;
|
unsigned idx = InvalidIdx;
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
|
|
||||||
StringRef funName = C.getCalleeName(CE);
|
StringRef funName = C.getCalleeName(CE);
|
||||||
if (funName.empty())
|
if (funName.empty())
|
||||||
|
@ -435,7 +435,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
||||||
|
|
||||||
void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
|
void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
StringRef funName = C.getCalleeName(CE);
|
StringRef funName = C.getCalleeName(CE);
|
||||||
|
|
||||||
// If a value has been allocated, add it to the set for tracking.
|
// If a value has been allocated, add it to the set for tracking.
|
||||||
|
@ -481,7 +481,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const ReturnStmt *S,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if the value is escaping through the return.
|
// Check if the value is escaping through the return.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const MemRegion *V =
|
const MemRegion *V =
|
||||||
state->getSVal(retExpr, C.getLocationContext()).getAsRegion();
|
state->getSVal(retExpr, C.getLocationContext()).getAsRegion();
|
||||||
if (!V)
|
if (!V)
|
||||||
|
@ -510,7 +510,7 @@ BugReport *MacOSKeychainAPIChecker::
|
||||||
|
|
||||||
void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
|
void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
AllocatedSetTy ASet = State->get<AllocatedData>();
|
AllocatedSetTy ASet = State->get<AllocatedData>();
|
||||||
if (ASet.isEmpty())
|
if (ASet.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -547,7 +547,7 @@ void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
|
||||||
|
|
||||||
// TODO: Remove this after we ensure that checkDeadSymbols are always called.
|
// TODO: Remove this after we ensure that checkDeadSymbols are always called.
|
||||||
void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const {
|
void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const {
|
||||||
const ProgramState *state = Ctx.getState();
|
ProgramStateRef state = Ctx.getState();
|
||||||
AllocatedSetTy AS = state->get<AllocatedData>();
|
AllocatedSetTy AS = state->get<AllocatedData>();
|
||||||
if (AS.isEmpty())
|
if (AS.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -56,7 +56,7 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
|
||||||
|
|
||||||
// Check if the first argument is stack allocated. If so, issue a warning
|
// Check if the first argument is stack allocated. If so, issue a warning
|
||||||
// because that's likely to be bad news.
|
// because that's likely to be bad news.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const MemRegion *R =
|
const MemRegion *R =
|
||||||
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
|
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
|
||||||
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
|
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
||||||
void checkEndPath(CheckerContext &C) const;
|
void checkEndPath(CheckerContext &C) const;
|
||||||
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
|
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
|
||||||
const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
|
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
|
||||||
bool Assumption) const;
|
bool Assumption) const;
|
||||||
void checkLocation(SVal l, bool isLoad, const Stmt *S,
|
void checkLocation(SVal l, bool isLoad, const Stmt *S,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
|
@ -97,22 +97,22 @@ private:
|
||||||
static void MallocMem(CheckerContext &C, const CallExpr *CE);
|
static void MallocMem(CheckerContext &C, const CallExpr *CE);
|
||||||
static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
|
static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
|
||||||
const OwnershipAttr* Att);
|
const OwnershipAttr* Att);
|
||||||
static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
|
static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
|
||||||
const Expr *SizeEx, SVal Init,
|
const Expr *SizeEx, SVal Init,
|
||||||
const ProgramState *state) {
|
ProgramStateRef state) {
|
||||||
return MallocMemAux(C, CE,
|
return MallocMemAux(C, CE,
|
||||||
state->getSVal(SizeEx, C.getLocationContext()),
|
state->getSVal(SizeEx, C.getLocationContext()),
|
||||||
Init, state);
|
Init, state);
|
||||||
}
|
}
|
||||||
static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
|
static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
|
||||||
SVal SizeEx, SVal Init,
|
SVal SizeEx, SVal Init,
|
||||||
const ProgramState *state);
|
ProgramStateRef state);
|
||||||
|
|
||||||
void FreeMem(CheckerContext &C, const CallExpr *CE) const;
|
void FreeMem(CheckerContext &C, const CallExpr *CE) const;
|
||||||
void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
||||||
const OwnershipAttr* Att) const;
|
const OwnershipAttr* Att) const;
|
||||||
const ProgramState *FreeMemAux(CheckerContext &C, const CallExpr *CE,
|
ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
|
||||||
const ProgramState *state, unsigned Num,
|
ProgramStateRef state, unsigned Num,
|
||||||
bool Hold) const;
|
bool Hold) const;
|
||||||
|
|
||||||
void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
|
void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
|
||||||
|
@ -198,7 +198,7 @@ bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
|
void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
|
||||||
const ProgramState *state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
|
ProgramStateRef state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
|
||||||
C.getState());
|
C.getState());
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
@ -210,20 +210,20 @@ void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
|
||||||
|
|
||||||
OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
|
OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
|
||||||
if (I != E) {
|
if (I != E) {
|
||||||
const ProgramState *state =
|
ProgramStateRef state =
|
||||||
MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
|
MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ProgramState *state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
|
ProgramStateRef state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
|
||||||
C.getState());
|
C.getState());
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *MallocChecker::MallocMemAux(CheckerContext &C,
|
ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
|
||||||
const CallExpr *CE,
|
const CallExpr *CE,
|
||||||
SVal Size, SVal Init,
|
SVal Size, SVal Init,
|
||||||
const ProgramState *state) {
|
ProgramStateRef state) {
|
||||||
unsigned Count = C.getCurrentBlockCount();
|
unsigned Count = C.getCurrentBlockCount();
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ const ProgramState *MallocChecker::MallocMemAux(CheckerContext &C,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
|
void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = FreeMemAux(C, CE, C.getState(), 0, false);
|
ProgramStateRef state = FreeMemAux(C, CE, C.getState(), 0, false);
|
||||||
|
|
||||||
if (state)
|
if (state)
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
|
@ -266,7 +266,7 @@ void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
||||||
|
|
||||||
for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
|
for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
const ProgramState *state =
|
ProgramStateRef state =
|
||||||
FreeMemAux(C, CE, C.getState(), *I,
|
FreeMemAux(C, CE, C.getState(), *I,
|
||||||
Att->getOwnKind() == OwnershipAttr::Holds);
|
Att->getOwnKind() == OwnershipAttr::Holds);
|
||||||
if (state)
|
if (state)
|
||||||
|
@ -274,9 +274,9 @@ void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *MallocChecker::FreeMemAux(CheckerContext &C,
|
ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
|
||||||
const CallExpr *CE,
|
const CallExpr *CE,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
unsigned Num,
|
unsigned Num,
|
||||||
bool Hold) const {
|
bool Hold) const {
|
||||||
const Expr *ArgExpr = CE->getArg(Num);
|
const Expr *ArgExpr = CE->getArg(Num);
|
||||||
|
@ -290,7 +290,7 @@ const ProgramState *MallocChecker::FreeMemAux(CheckerContext &C,
|
||||||
|
|
||||||
// FIXME: Technically using 'Assume' here can result in a path
|
// FIXME: Technically using 'Assume' here can result in a path
|
||||||
// bifurcation. In such cases we need to return two states, not just one.
|
// bifurcation. In such cases we need to return two states, not just one.
|
||||||
const ProgramState *notNullState, *nullState;
|
ProgramStateRef notNullState, nullState;
|
||||||
llvm::tie(notNullState, nullState) = state->assume(location);
|
llvm::tie(notNullState, nullState) = state->assume(location);
|
||||||
|
|
||||||
// The explicit NULL case, no operation is performed.
|
// The explicit NULL case, no operation is performed.
|
||||||
|
@ -499,7 +499,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const Expr *arg0Expr = CE->getArg(0);
|
const Expr *arg0Expr = CE->getArg(0);
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
DefinedOrUnknownSVal arg0Val
|
DefinedOrUnknownSVal arg0Val
|
||||||
|
@ -526,7 +526,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
||||||
|
|
||||||
// If the ptr is NULL and the size is not 0, the call is equivalent to
|
// If the ptr is NULL and the size is not 0, the call is equivalent to
|
||||||
// malloc(size).
|
// malloc(size).
|
||||||
const ProgramState *stateEqual = state->assume(PtrEQ, true);
|
ProgramStateRef stateEqual = state->assume(PtrEQ, true);
|
||||||
if (stateEqual && state->assume(SizeZero, false)) {
|
if (stateEqual && state->assume(SizeZero, false)) {
|
||||||
// Hack: set the NULL symbolic region to released to suppress false warning.
|
// Hack: set the NULL symbolic region to released to suppress false warning.
|
||||||
// In the future we should add more states for allocated regions, e.g.,
|
// In the future we should add more states for allocated regions, e.g.,
|
||||||
|
@ -536,28 +536,28 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
||||||
if (Sym)
|
if (Sym)
|
||||||
stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
|
stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
|
||||||
|
|
||||||
const ProgramState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
|
ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
|
||||||
UndefinedVal(), stateEqual);
|
UndefinedVal(), stateEqual);
|
||||||
C.addTransition(stateMalloc);
|
C.addTransition(stateMalloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const ProgramState *stateNotEqual = state->assume(PtrEQ, false)) {
|
if (ProgramStateRef stateNotEqual = state->assume(PtrEQ, false)) {
|
||||||
// If the size is 0, free the memory.
|
// If the size is 0, free the memory.
|
||||||
if (const ProgramState *stateSizeZero =
|
if (ProgramStateRef stateSizeZero =
|
||||||
stateNotEqual->assume(SizeZero, true))
|
stateNotEqual->assume(SizeZero, true))
|
||||||
if (const ProgramState *stateFree =
|
if (ProgramStateRef stateFree =
|
||||||
FreeMemAux(C, CE, stateSizeZero, 0, false)) {
|
FreeMemAux(C, CE, stateSizeZero, 0, false)) {
|
||||||
|
|
||||||
// Bind the return value to NULL because it is now free.
|
// Bind the return value to NULL because it is now free.
|
||||||
C.addTransition(stateFree->BindExpr(CE, LCtx,
|
C.addTransition(stateFree->BindExpr(CE, LCtx,
|
||||||
svalBuilder.makeNull(), true));
|
svalBuilder.makeNull(), true));
|
||||||
}
|
}
|
||||||
if (const ProgramState *stateSizeNotZero =
|
if (ProgramStateRef stateSizeNotZero =
|
||||||
stateNotEqual->assume(SizeZero,false))
|
stateNotEqual->assume(SizeZero,false))
|
||||||
if (const ProgramState *stateFree = FreeMemAux(C, CE, stateSizeNotZero,
|
if (ProgramStateRef stateFree = FreeMemAux(C, CE, stateSizeNotZero,
|
||||||
0, false)) {
|
0, false)) {
|
||||||
// FIXME: We should copy the content of the original buffer.
|
// FIXME: We should copy the content of the original buffer.
|
||||||
const ProgramState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
|
ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
|
||||||
UnknownVal(), stateFree);
|
UnknownVal(), stateFree);
|
||||||
C.addTransition(stateRealloc);
|
C.addTransition(stateRealloc);
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
|
void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
SVal count = state->getSVal(CE->getArg(0), LCtx);
|
SVal count = state->getSVal(CE->getArg(0), LCtx);
|
||||||
|
@ -583,7 +583,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
if (!SymReaper.hasDeadSymbols())
|
if (!SymReaper.hasDeadSymbols())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
RegionStateTy RS = state->get<RegionState>();
|
RegionStateTy RS = state->get<RegionState>();
|
||||||
RegionStateTy::Factory &F = state->get_context<RegionState>();
|
RegionStateTy::Factory &F = state->get_context<RegionState>();
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
|
void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
|
||||||
const ProgramState *state = Ctx.getState();
|
ProgramStateRef state = Ctx.getState();
|
||||||
RegionStateTy M = state->get<RegionState>();
|
RegionStateTy M = state->get<RegionState>();
|
||||||
|
|
||||||
for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||||
|
@ -638,7 +638,7 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
|
||||||
if (!retExpr)
|
if (!retExpr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
SymbolRef Sym = state->getSVal(retExpr, C.getLocationContext()).getAsSymbol();
|
SymbolRef Sym = state->getSVal(retExpr, C.getLocationContext()).getAsSymbol();
|
||||||
if (!Sym)
|
if (!Sym)
|
||||||
|
@ -655,7 +655,7 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *MallocChecker::evalAssume(const ProgramState *state,
|
ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
|
||||||
SVal Cond,
|
SVal Cond,
|
||||||
bool Assumption) const {
|
bool Assumption) const {
|
||||||
// If a symblic region is assumed to NULL, set its state to AllocateFailed.
|
// If a symblic region is assumed to NULL, set its state to AllocateFailed.
|
||||||
|
@ -699,7 +699,7 @@ void MallocChecker::checkBind(SVal location, SVal val,
|
||||||
// assignment, let it go. However, assigning to fields of a stack-storage
|
// assignment, let it go. However, assigning to fields of a stack-storage
|
||||||
// structure does not transfer ownership.
|
// structure does not transfer ownership.
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
|
DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
|
||||||
|
|
||||||
// Check for null dereferences.
|
// Check for null dereferences.
|
||||||
|
@ -712,7 +712,7 @@ void MallocChecker::checkBind(SVal location, SVal val,
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
if (const RefState *RS = state->get<RegionState>(Sym)) {
|
if (const RefState *RS = state->get<RegionState>(Sym)) {
|
||||||
// If ptr is NULL, no operation is performed.
|
// If ptr is NULL, no operation is performed.
|
||||||
const ProgramState *notNullState, *nullState;
|
ProgramStateRef notNullState, nullState;
|
||||||
llvm::tie(notNullState, nullState) = state->assume(l);
|
llvm::tie(notNullState, nullState) = state->assume(l);
|
||||||
|
|
||||||
// Generate a transition for 'nullState' to record the assumption
|
// Generate a transition for 'nullState' to record the assumption
|
||||||
|
|
|
@ -182,7 +182,7 @@ namespace ento {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool hasFlag(SVal val, const ProgramState *state) {
|
static bool hasFlag(SVal val, ProgramStateRef state) {
|
||||||
if (SymbolRef sym = val.getAsSymbol())
|
if (SymbolRef sym = val.getAsSymbol())
|
||||||
if (const unsigned *attachedFlags = state->get<T>(sym))
|
if (const unsigned *attachedFlags = state->get<T>(sym))
|
||||||
return *attachedFlags;
|
return *attachedFlags;
|
||||||
|
@ -190,7 +190,7 @@ static bool hasFlag(SVal val, const ProgramState *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void setFlag(const ProgramState *state, SVal val, CheckerContext &C) {
|
static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C) {
|
||||||
// We tag the symbol that the SVal wraps.
|
// We tag the symbol that the SVal wraps.
|
||||||
if (SymbolRef sym = val.getAsSymbol())
|
if (SymbolRef sym = val.getAsSymbol())
|
||||||
C.addTransition(state->set<T>(sym, true));
|
C.addTransition(state->set<T>(sym, true));
|
||||||
|
@ -220,7 +220,7 @@ void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASTContext &Ctx = C.getASTContext();
|
ASTContext &Ctx = C.getASTContext();
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
// If we are loading from NSError**/CFErrorRef* parameter, mark the resulting
|
// If we are loading from NSError**/CFErrorRef* parameter, mark the resulting
|
||||||
// SVal so that we can later check it when handling the
|
// SVal so that we can later check it when handling the
|
||||||
|
@ -253,7 +253,7 @@ void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SVal loc = event.Location;
|
SVal loc = event.Location;
|
||||||
const ProgramState *state = event.SinkNode->getState();
|
ProgramStateRef state = event.SinkNode->getState();
|
||||||
BugReporter &BR = *event.BR;
|
BugReporter &BR = *event.BR;
|
||||||
|
|
||||||
bool isNSError = hasFlag<NSErrorOut>(loc, state);
|
bool isNSError = hasFlag<NSErrorOut>(loc, state);
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
|
|
||||||
void NoReturnFunctionChecker::checkPostStmt(const CallExpr *CE,
|
void NoReturnFunctionChecker::checkPostStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const Expr *Callee = CE->getCallee();
|
const Expr *Callee = CE->getCallee();
|
||||||
|
|
||||||
bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
|
bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
|
||||||
|
|
|
@ -35,7 +35,7 @@ private:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef getCalleeName(const ProgramState *State,
|
static StringRef getCalleeName(ProgramStateRef State,
|
||||||
const CallExpr *CE,
|
const CallExpr *CE,
|
||||||
const LocationContext *LCtx) {
|
const LocationContext *LCtx) {
|
||||||
const Expr *Callee = CE->getCallee();
|
const Expr *Callee = CE->getCallee();
|
||||||
|
@ -104,7 +104,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
|
||||||
static SimpleProgramPointTag OSAtomicStoreTag("OSAtomicChecker : Store");
|
static SimpleProgramPointTag OSAtomicStoreTag("OSAtomicChecker : Store");
|
||||||
|
|
||||||
// Load 'theValue'.
|
// Load 'theValue'.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
ExplodedNodeSet Tmp;
|
ExplodedNodeSet Tmp;
|
||||||
SVal location = state->getSVal(theValueExpr, LCtx);
|
SVal location = state->getSVal(theValueExpr, LCtx);
|
||||||
|
@ -133,7 +133,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
|
|
||||||
ExplodedNode *N = *I;
|
ExplodedNode *N = *I;
|
||||||
const ProgramState *stateLoad = N->getState();
|
ProgramStateRef stateLoad = N->getState();
|
||||||
|
|
||||||
// Use direct bindings from the environment since we are forcing a load
|
// Use direct bindings from the environment since we are forcing a load
|
||||||
// from a location that the Environment would typically not be used
|
// from a location that the Environment would typically not be used
|
||||||
|
@ -158,7 +158,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
|
||||||
DefinedOrUnknownSVal Cmp =
|
DefinedOrUnknownSVal Cmp =
|
||||||
svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
|
svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
|
||||||
|
|
||||||
const ProgramState *stateEqual = stateLoad->assume(Cmp, true);
|
ProgramStateRef stateEqual = stateLoad->assume(Cmp, true);
|
||||||
|
|
||||||
// Were they equal?
|
// Were they equal?
|
||||||
if (stateEqual) {
|
if (stateEqual) {
|
||||||
|
@ -186,7 +186,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
|
||||||
for (ExplodedNodeSet::iterator I2 = TmpStore.begin(),
|
for (ExplodedNodeSet::iterator I2 = TmpStore.begin(),
|
||||||
E2 = TmpStore.end(); I2 != E2; ++I2) {
|
E2 = TmpStore.end(); I2 != E2; ++I2) {
|
||||||
ExplodedNode *predNew = *I2;
|
ExplodedNode *predNew = *I2;
|
||||||
const ProgramState *stateNew = predNew->getState();
|
ProgramStateRef stateNew = predNew->getState();
|
||||||
// Check for 'void' return type if we have a bogus function prototype.
|
// Check for 'void' return type if we have a bogus function prototype.
|
||||||
SVal Res = UnknownVal();
|
SVal Res = UnknownVal();
|
||||||
QualType T = CE->getType();
|
QualType T = CE->getType();
|
||||||
|
@ -198,7 +198,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Were they not equal?
|
// Were they not equal?
|
||||||
if (const ProgramState *stateNotEqual = stateLoad->assume(Cmp, false)) {
|
if (ProgramStateRef stateNotEqual = stateLoad->assume(Cmp, false)) {
|
||||||
// Check for 'void' return type if we have a bogus function prototype.
|
// Check for 'void' return type if we have a bogus function prototype.
|
||||||
SVal Res = UnknownVal();
|
SVal Res = UnknownVal();
|
||||||
QualType T = CE->getType();
|
QualType T = CE->getType();
|
||||||
|
|
|
@ -38,7 +38,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
|
|
||||||
const Expr *Ex = S->getSynchExpr();
|
const Expr *Ex = S->getSynchExpr();
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SVal V = state->getSVal(Ex, C.getLocationContext());
|
SVal V = state->getSVal(Ex, C.getLocationContext());
|
||||||
|
|
||||||
// Uninitialized value used for the mutex?
|
// Uninitialized value used for the mutex?
|
||||||
|
@ -59,7 +59,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for null mutexes.
|
// Check for null mutexes.
|
||||||
const ProgramState *notNullState, *nullState;
|
ProgramStateRef notNullState, nullState;
|
||||||
llvm::tie(notNullState, nullState) = state->assume(cast<DefinedSVal>(V));
|
llvm::tie(notNullState, nullState) = state->assume(cast<DefinedSVal>(V));
|
||||||
|
|
||||||
if (nullState) {
|
if (nullState) {
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace ento {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SelfFlagEnum getSelfFlags(SVal val, const ProgramState *state) {
|
static SelfFlagEnum getSelfFlags(SVal val, ProgramStateRef state) {
|
||||||
if (SymbolRef sym = val.getAsSymbol())
|
if (SymbolRef sym = val.getAsSymbol())
|
||||||
if (const unsigned *attachedFlags = state->get<SelfFlag>(sym))
|
if (const unsigned *attachedFlags = state->get<SelfFlag>(sym))
|
||||||
return (SelfFlagEnum)*attachedFlags;
|
return (SelfFlagEnum)*attachedFlags;
|
||||||
|
@ -141,7 +141,7 @@ static SelfFlagEnum getSelfFlags(SVal val, CheckerContext &C) {
|
||||||
return getSelfFlags(val, C.getState());
|
return getSelfFlags(val, C.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addSelfFlag(const ProgramState *state, SVal val,
|
static void addSelfFlag(ProgramStateRef state, SVal val,
|
||||||
SelfFlagEnum flag, CheckerContext &C) {
|
SelfFlagEnum flag, CheckerContext &C) {
|
||||||
// We tag the symbol that the SVal wraps.
|
// We tag the symbol that the SVal wraps.
|
||||||
if (SymbolRef sym = val.getAsSymbol())
|
if (SymbolRef sym = val.getAsSymbol())
|
||||||
|
@ -199,7 +199,7 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
|
||||||
|
|
||||||
if (isInitMessage(msg)) {
|
if (isInitMessage(msg)) {
|
||||||
// Tag the return value as the result of an initializer.
|
// Tag the return value as the result of an initializer.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
// FIXME this really should be context sensitive, where we record
|
// FIXME this really should be context sensitive, where we record
|
||||||
// the current stack frame (for IPA). Also, we need to clean this
|
// the current stack frame (for IPA). Also, we need to clean this
|
||||||
|
@ -259,7 +259,7 @@ void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
|
||||||
|
|
||||||
void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
|
void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
for (CallExpr::const_arg_iterator
|
for (CallExpr::const_arg_iterator
|
||||||
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
|
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
|
||||||
SVal argV = state->getSVal(*I, C.getLocationContext());
|
SVal argV = state->getSVal(*I, C.getLocationContext());
|
||||||
|
@ -277,7 +277,7 @@ void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
|
||||||
|
|
||||||
void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
|
void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
for (CallExpr::const_arg_iterator
|
for (CallExpr::const_arg_iterator
|
||||||
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
|
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
|
||||||
|
@ -301,7 +301,7 @@ void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
// Tag the result of a load from 'self' so that we can easily know that the
|
// Tag the result of a load from 'self' so that we can easily know that the
|
||||||
// value is the object that 'self' points to.
|
// value is the object that 'self' points to.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (isSelfVar(location, C))
|
if (isSelfVar(location, C))
|
||||||
addSelfFlag(state, state->getSVal(cast<Loc>(location)), SelfFlag_Self, C);
|
addSelfFlag(state, state->getSVal(cast<Loc>(location)), SelfFlag_Self, C);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *B,
|
||||||
if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add)
|
if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
SVal LV = state->getSVal(B->getLHS(), LCtx);
|
SVal LV = state->getSVal(B->getLHS(), LCtx);
|
||||||
SVal RV = state->getSVal(B->getRHS(), LCtx);
|
SVal RV = state->getSVal(B->getRHS(), LCtx);
|
||||||
|
|
|
@ -39,7 +39,7 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
|
||||||
if (B->getOpcode() != BO_Sub)
|
if (B->getOpcode() != BO_Sub)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
SVal LV = state->getSVal(B->getLHS(), LCtx);
|
SVal LV = state->getSVal(B->getLHS(), LCtx);
|
||||||
SVal RV = state->getSVal(B->getRHS(), LCtx);
|
SVal RV = state->getSVal(B->getRHS(), LCtx);
|
||||||
|
|
|
@ -56,7 +56,7 @@ template <> struct ProgramStateTrait<LockSet> :
|
||||||
|
|
||||||
void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
|
void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
StringRef FName = C.getCalleeName(CE);
|
StringRef FName = C.getCalleeName(CE);
|
||||||
if (FName.empty())
|
if (FName.empty())
|
||||||
|
@ -100,7 +100,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
|
||||||
if (!lockR)
|
if (!lockR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
SVal X = state->getSVal(CE, C.getLocationContext());
|
SVal X = state->getSVal(CE, C.getLocationContext());
|
||||||
if (X.isUnknownOrUndef())
|
if (X.isUnknownOrUndef())
|
||||||
|
@ -122,10 +122,10 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *lockSucc = state;
|
ProgramStateRef lockSucc = state;
|
||||||
if (isTryLock) {
|
if (isTryLock) {
|
||||||
// Bifurcate the state, and allow a mode where the lock acquisition fails.
|
// Bifurcate the state, and allow a mode where the lock acquisition fails.
|
||||||
const ProgramState *lockFail;
|
ProgramStateRef lockFail;
|
||||||
switch (semantics) {
|
switch (semantics) {
|
||||||
case PthreadSemantics:
|
case PthreadSemantics:
|
||||||
llvm::tie(lockFail, lockSucc) = state->assume(retVal);
|
llvm::tie(lockFail, lockSucc) = state->assume(retVal);
|
||||||
|
@ -162,7 +162,7 @@ void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
|
||||||
if (!lockR)
|
if (!lockR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
llvm::ImmutableList<const MemRegion*> LS = state->get<LockSet>();
|
llvm::ImmutableList<const MemRegion*> LS = state->get<LockSet>();
|
||||||
|
|
||||||
// FIXME: Better analysis requires IPA for wrappers.
|
// FIXME: Better analysis requires IPA for wrappers.
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
const ProgramPointTag *t = 0)
|
const ProgramPointTag *t = 0)
|
||||||
: C(&c), tag(t){}
|
: C(&c), tag(t){}
|
||||||
|
|
||||||
ExplodedNode *MakeNode(const ProgramState *state, ExplodedNode *Pred,
|
ExplodedNode *MakeNode(ProgramStateRef state, ExplodedNode *Pred,
|
||||||
bool MarkAsSink = false) {
|
bool MarkAsSink = false) {
|
||||||
return C->addTransition(state, Pred, tag, MarkAsSink);
|
return C->addTransition(state, Pred, tag, MarkAsSink);
|
||||||
}
|
}
|
||||||
|
@ -732,7 +732,7 @@ public:
|
||||||
const RetainSummary *getSummary(const FunctionDecl *FD);
|
const RetainSummary *getSummary(const FunctionDecl *FD);
|
||||||
|
|
||||||
const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
|
const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const LocationContext *LC);
|
const LocationContext *LC);
|
||||||
|
|
||||||
const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
|
const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
|
||||||
|
@ -1298,7 +1298,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl *MD,
|
||||||
|
|
||||||
const RetainSummary *
|
const RetainSummary *
|
||||||
RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
|
RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const LocationContext *LC) {
|
const LocationContext *LC) {
|
||||||
|
|
||||||
// We need the type-information of the tracked receiver object
|
// We need the type-information of the tracked receiver object
|
||||||
|
@ -1553,13 +1553,13 @@ template<> struct ProgramStateTrait<AutoreleasePoolContents>
|
||||||
} // end GR namespace
|
} // end GR namespace
|
||||||
} // end clang namespace
|
} // end clang namespace
|
||||||
|
|
||||||
static SymbolRef GetCurrentAutoreleasePool(const ProgramState *state) {
|
static SymbolRef GetCurrentAutoreleasePool(ProgramStateRef state) {
|
||||||
ARStack stack = state->get<AutoreleaseStack>();
|
ARStack stack = state->get<AutoreleaseStack>();
|
||||||
return stack.isEmpty() ? SymbolRef() : stack.getHead();
|
return stack.isEmpty() ? SymbolRef() : stack.getHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ProgramState *
|
static ProgramStateRef
|
||||||
SendAutorelease(const ProgramState *state,
|
SendAutorelease(ProgramStateRef state,
|
||||||
ARCounts::Factory &F,
|
ARCounts::Factory &F,
|
||||||
SymbolRef sym) {
|
SymbolRef sym) {
|
||||||
SymbolRef pool = GetCurrentAutoreleasePool(state);
|
SymbolRef pool = GetCurrentAutoreleasePool(state);
|
||||||
|
@ -1838,8 +1838,8 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Check if the type state has changed.
|
// Check if the type state has changed.
|
||||||
const ProgramState *PrevSt = PrevN->getState();
|
ProgramStateRef PrevSt = PrevN->getState();
|
||||||
const ProgramState *CurrSt = N->getState();
|
ProgramStateRef CurrSt = N->getState();
|
||||||
const LocationContext *LCtx = N->getLocationContext();
|
const LocationContext *LCtx = N->getLocationContext();
|
||||||
|
|
||||||
const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
|
const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
|
||||||
|
@ -2121,7 +2121,7 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
|
||||||
const MemRegion* FirstBinding = 0;
|
const MemRegion* FirstBinding = 0;
|
||||||
|
|
||||||
while (N) {
|
while (N) {
|
||||||
const ProgramState *St = N->getState();
|
ProgramStateRef St = N->getState();
|
||||||
RefBindings B = St->get<RefBindings>();
|
RefBindings B = St->get<RefBindings>();
|
||||||
|
|
||||||
if (!B.lookup(Sym))
|
if (!B.lookup(Sym))
|
||||||
|
@ -2416,7 +2416,7 @@ public:
|
||||||
return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled());
|
return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
void printState(raw_ostream &Out, const ProgramState *State,
|
void printState(raw_ostream &Out, ProgramStateRef State,
|
||||||
const char *NL, const char *Sep) const;
|
const char *NL, const char *Sep) const;
|
||||||
|
|
||||||
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
|
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
|
||||||
|
@ -2431,47 +2431,47 @@ public:
|
||||||
|
|
||||||
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
|
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
|
||||||
|
|
||||||
const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
|
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
|
||||||
bool Assumption) const;
|
bool Assumption) const;
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
checkRegionChanges(const ProgramState *state,
|
checkRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) const;
|
ArrayRef<const MemRegion *> Regions) const;
|
||||||
|
|
||||||
bool wantsRegionChangeUpdate(const ProgramState *state) const {
|
bool wantsRegionChangeUpdate(ProgramStateRef state) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
|
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
|
||||||
void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
|
void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
|
||||||
ExplodedNode *Pred, RetEffect RE, RefVal X,
|
ExplodedNode *Pred, RetEffect RE, RefVal X,
|
||||||
SymbolRef Sym, const ProgramState *state) const;
|
SymbolRef Sym, ProgramStateRef state) const;
|
||||||
|
|
||||||
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
||||||
void checkEndPath(CheckerContext &C) const;
|
void checkEndPath(CheckerContext &C) const;
|
||||||
|
|
||||||
const ProgramState *updateSymbol(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
|
||||||
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
|
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
|
|
||||||
void processNonLeakError(const ProgramState *St, SourceRange ErrorRange,
|
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
|
||||||
RefVal::Kind ErrorKind, SymbolRef Sym,
|
RefVal::Kind ErrorKind, SymbolRef Sym,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
|
|
||||||
const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
|
const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
|
||||||
|
|
||||||
const ProgramState *handleSymbolDeath(const ProgramState *state,
|
ProgramStateRef handleSymbolDeath(ProgramStateRef state,
|
||||||
SymbolRef sid, RefVal V,
|
SymbolRef sid, RefVal V,
|
||||||
SmallVectorImpl<SymbolRef> &Leaked) const;
|
SmallVectorImpl<SymbolRef> &Leaked) const;
|
||||||
|
|
||||||
std::pair<ExplodedNode *, const ProgramState *>
|
std::pair<ExplodedNode *, ProgramStateRef >
|
||||||
handleAutoreleaseCounts(const ProgramState *state,
|
handleAutoreleaseCounts(ProgramStateRef state,
|
||||||
GenericNodeBuilderRefCount Bd, ExplodedNode *Pred,
|
GenericNodeBuilderRefCount Bd, ExplodedNode *Pred,
|
||||||
CheckerContext &Ctx, SymbolRef Sym, RefVal V) const;
|
CheckerContext &Ctx, SymbolRef Sym, RefVal V) const;
|
||||||
|
|
||||||
ExplodedNode *processLeaks(const ProgramState *state,
|
ExplodedNode *processLeaks(ProgramStateRef state,
|
||||||
SmallVectorImpl<SymbolRef> &Leaked,
|
SmallVectorImpl<SymbolRef> &Leaked,
|
||||||
GenericNodeBuilderRefCount &Builder,
|
GenericNodeBuilderRefCount &Builder,
|
||||||
CheckerContext &Ctx,
|
CheckerContext &Ctx,
|
||||||
|
@ -2481,10 +2481,10 @@ public:
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class StopTrackingCallback : public SymbolVisitor {
|
class StopTrackingCallback : public SymbolVisitor {
|
||||||
const ProgramState *state;
|
ProgramStateRef state;
|
||||||
public:
|
public:
|
||||||
StopTrackingCallback(const ProgramState *st) : state(st) {}
|
StopTrackingCallback(ProgramStateRef st) : state(st) {}
|
||||||
const ProgramState *getState() const { return state; }
|
ProgramStateRef getState() const { return state; }
|
||||||
|
|
||||||
bool VisitSymbol(SymbolRef sym) {
|
bool VisitSymbol(SymbolRef sym) {
|
||||||
state = state->remove<RefBindings>(sym);
|
state = state->remove<RefBindings>(sym);
|
||||||
|
@ -2505,7 +2505,7 @@ void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
|
||||||
if (!BE->getBlockDecl()->hasCaptures())
|
if (!BE->getBlockDecl()->hasCaptures())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const BlockDataRegion *R =
|
const BlockDataRegion *R =
|
||||||
cast<BlockDataRegion>(state->getSVal(BE,
|
cast<BlockDataRegion>(state->getSVal(BE,
|
||||||
C.getLocationContext()).getAsRegion());
|
C.getLocationContext()).getAsRegion());
|
||||||
|
@ -2557,7 +2557,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
|
SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
|
||||||
if (!Sym)
|
if (!Sym)
|
||||||
return;
|
return;
|
||||||
|
@ -2580,7 +2580,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
|
||||||
void RetainCountChecker::checkPostStmt(const CallExpr *CE,
|
void RetainCountChecker::checkPostStmt(const CallExpr *CE,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
// Get the callee.
|
// Get the callee.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const Expr *Callee = CE->getCallee();
|
const Expr *Callee = CE->getCallee();
|
||||||
SVal L = state->getSVal(Callee, C.getLocationContext());
|
SVal L = state->getSVal(Callee, C.getLocationContext());
|
||||||
|
|
||||||
|
@ -2618,13 +2618,13 @@ void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE,
|
||||||
if (!Summ)
|
if (!Summ)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
|
checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg,
|
void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
RetainSummaryManager &Summaries = getSummaryManager(C);
|
RetainSummaryManager &Summaries = getSummaryManager(C);
|
||||||
|
|
||||||
|
@ -2674,7 +2674,7 @@ static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
|
||||||
void RetainCountChecker::checkSummary(const RetainSummary &Summ,
|
void RetainCountChecker::checkSummary(const RetainSummary &Summ,
|
||||||
const CallOrObjCMessage &CallOrMsg,
|
const CallOrObjCMessage &CallOrMsg,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
// Evaluate the effect of the arguments.
|
// Evaluate the effect of the arguments.
|
||||||
RefVal::Kind hasErr = (RefVal::Kind) 0;
|
RefVal::Kind hasErr = (RefVal::Kind) 0;
|
||||||
|
@ -2802,8 +2802,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
RetainCountChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
|
RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
|
||||||
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
|
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
// In GC mode [... release] and [... retain] do nothing.
|
// In GC mode [... release] and [... retain] do nothing.
|
||||||
|
@ -2939,7 +2939,7 @@ RetainCountChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
|
||||||
return state->set<RefBindings>(sym, V);
|
return state->set<RefBindings>(sym, V);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RetainCountChecker::processNonLeakError(const ProgramState *St,
|
void RetainCountChecker::processNonLeakError(ProgramStateRef St,
|
||||||
SourceRange ErrorRange,
|
SourceRange ErrorRange,
|
||||||
RefVal::Kind ErrorKind,
|
RefVal::Kind ErrorKind,
|
||||||
SymbolRef Sym,
|
SymbolRef Sym,
|
||||||
|
@ -2988,7 +2988,7 @@ void RetainCountChecker::processNonLeakError(const ProgramState *St,
|
||||||
|
|
||||||
bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
||||||
// Get the callee. We're only interested in simple C functions.
|
// Get the callee. We're only interested in simple C functions.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
const FunctionDecl *FD = C.getCalleeDecl(CE);
|
||||||
if (!FD)
|
if (!FD)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3071,7 +3071,7 @@ void RetainCountChecker::checkPreStmt(const ReturnStmt *S,
|
||||||
if (!RetE)
|
if (!RetE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SymbolRef Sym =
|
SymbolRef Sym =
|
||||||
state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
|
state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
|
||||||
if (!Sym)
|
if (!Sym)
|
||||||
|
@ -3163,7 +3163,7 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
RetEffect RE, RefVal X,
|
RetEffect RE, RefVal X,
|
||||||
SymbolRef Sym,
|
SymbolRef Sym,
|
||||||
const ProgramState *state) const {
|
ProgramStateRef state) const {
|
||||||
// Any leaks or other errors?
|
// Any leaks or other errors?
|
||||||
if (X.isReturnedOwned() && X.getCount() == 0) {
|
if (X.isReturnedOwned() && X.getCount() == 0) {
|
||||||
if (RE.getKind() != RetEffect::NoRet) {
|
if (RE.getKind() != RetEffect::NoRet) {
|
||||||
|
@ -3240,7 +3240,7 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
|
||||||
// (2) we are binding to a memregion that does not have stack storage
|
// (2) we are binding to a memregion that does not have stack storage
|
||||||
// (3) we are binding to a memregion with stack storage that the store
|
// (3) we are binding to a memregion with stack storage that the store
|
||||||
// does not understand.
|
// does not understand.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
|
if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
|
||||||
escapes = !regionLoc->getRegion()->hasStackStorage();
|
escapes = !regionLoc->getRegion()->hasStackStorage();
|
||||||
|
@ -3265,7 +3265,7 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *RetainCountChecker::evalAssume(const ProgramState *state,
|
ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
|
||||||
SVal Cond,
|
SVal Cond,
|
||||||
bool Assumption) const {
|
bool Assumption) const {
|
||||||
|
|
||||||
|
@ -3298,8 +3298,8 @@ const ProgramState *RetainCountChecker::evalAssume(const ProgramState *state,
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
RetainCountChecker::checkRegionChanges(const ProgramState *state,
|
RetainCountChecker::checkRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) const {
|
ArrayRef<const MemRegion *> Regions) const {
|
||||||
|
@ -3328,8 +3328,8 @@ RetainCountChecker::checkRegionChanges(const ProgramState *state,
|
||||||
// Handle dead symbols and end-of-path.
|
// Handle dead symbols and end-of-path.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
std::pair<ExplodedNode *, const ProgramState *>
|
std::pair<ExplodedNode *, ProgramStateRef >
|
||||||
RetainCountChecker::handleAutoreleaseCounts(const ProgramState *state,
|
RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
|
||||||
GenericNodeBuilderRefCount Bd,
|
GenericNodeBuilderRefCount Bd,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
CheckerContext &Ctx,
|
CheckerContext &Ctx,
|
||||||
|
@ -3389,11 +3389,11 @@ RetainCountChecker::handleAutoreleaseCounts(const ProgramState *state,
|
||||||
Ctx.EmitReport(report);
|
Ctx.EmitReport(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair((ExplodedNode *)0, (const ProgramState *)0);
|
return std::make_pair((ExplodedNode *)0, (ProgramStateRef )0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
RetainCountChecker::handleSymbolDeath(const ProgramState *state,
|
RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
|
||||||
SymbolRef sid, RefVal V,
|
SymbolRef sid, RefVal V,
|
||||||
SmallVectorImpl<SymbolRef> &Leaked) const {
|
SmallVectorImpl<SymbolRef> &Leaked) const {
|
||||||
bool hasLeak = false;
|
bool hasLeak = false;
|
||||||
|
@ -3410,7 +3410,7 @@ RetainCountChecker::handleSymbolDeath(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplodedNode *
|
ExplodedNode *
|
||||||
RetainCountChecker::processLeaks(const ProgramState *state,
|
RetainCountChecker::processLeaks(ProgramStateRef state,
|
||||||
SmallVectorImpl<SymbolRef> &Leaked,
|
SmallVectorImpl<SymbolRef> &Leaked,
|
||||||
GenericNodeBuilderRefCount &Builder,
|
GenericNodeBuilderRefCount &Builder,
|
||||||
CheckerContext &Ctx,
|
CheckerContext &Ctx,
|
||||||
|
@ -3441,7 +3441,7 @@ RetainCountChecker::processLeaks(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
void RetainCountChecker::checkEndPath(CheckerContext &Ctx) const {
|
void RetainCountChecker::checkEndPath(CheckerContext &Ctx) const {
|
||||||
const ProgramState *state = Ctx.getState();
|
ProgramStateRef state = Ctx.getState();
|
||||||
GenericNodeBuilderRefCount Bd(Ctx);
|
GenericNodeBuilderRefCount Bd(Ctx);
|
||||||
RefBindings B = state->get<RefBindings>();
|
RefBindings B = state->get<RefBindings>();
|
||||||
ExplodedNode *Pred = Ctx.getPredecessor();
|
ExplodedNode *Pred = Ctx.getPredecessor();
|
||||||
|
@ -3479,7 +3479,7 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
ExplodedNode *Pred = C.getPredecessor();
|
ExplodedNode *Pred = C.getPredecessor();
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
RefBindings B = state->get<RefBindings>();
|
RefBindings B = state->get<RefBindings>();
|
||||||
|
|
||||||
// Update counts from autorelease pools
|
// Update counts from autorelease pools
|
||||||
|
@ -3531,7 +3531,7 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void PrintPool(raw_ostream &Out, SymbolRef Sym,
|
static void PrintPool(raw_ostream &Out, SymbolRef Sym,
|
||||||
const ProgramState *State) {
|
ProgramStateRef State) {
|
||||||
Out << ' ';
|
Out << ' ';
|
||||||
if (Sym)
|
if (Sym)
|
||||||
Sym->dumpToStream(Out);
|
Sym->dumpToStream(Out);
|
||||||
|
@ -3547,14 +3547,14 @@ static void PrintPool(raw_ostream &Out, SymbolRef Sym,
|
||||||
Out << '}';
|
Out << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool UsesAutorelease(const ProgramState *state) {
|
static bool UsesAutorelease(ProgramStateRef state) {
|
||||||
// A state uses autorelease if it allocated an autorelease pool or if it has
|
// A state uses autorelease if it allocated an autorelease pool or if it has
|
||||||
// objects in the caller's autorelease pool.
|
// objects in the caller's autorelease pool.
|
||||||
return !state->get<AutoreleaseStack>().isEmpty() ||
|
return !state->get<AutoreleaseStack>().isEmpty() ||
|
||||||
state->get<AutoreleasePoolContents>(SymbolRef());
|
state->get<AutoreleasePoolContents>(SymbolRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RetainCountChecker::printState(raw_ostream &Out, const ProgramState *State,
|
void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
|
||||||
const char *NL, const char *Sep) const {
|
const char *NL, const char *Sep) const {
|
||||||
|
|
||||||
RefBindings B = State->get<RefBindings>();
|
RefBindings B = State->get<RefBindings>();
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
|
|
||||||
void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
const Expr *RetE = RS->getRetValue();
|
const Expr *RetE = RS->getRetValue();
|
||||||
if (!RetE)
|
if (!RetE)
|
||||||
|
@ -58,8 +58,8 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
||||||
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
|
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
|
||||||
ER->getValueType());
|
ER->getValueType());
|
||||||
|
|
||||||
const ProgramState *StInBound = state->assumeInBound(Idx, NumElements, true);
|
ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
|
||||||
const ProgramState *StOutBound = state->assumeInBound(Idx, NumElements, false);
|
ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
|
||||||
if (StOutBound && !StInBound) {
|
if (StOutBound && !StInBound) {
|
||||||
ExplodedNode *N = C.generateSink(StOutBound);
|
ExplodedNode *N = C.generateSink(StOutBound);
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {
|
void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {
|
||||||
const ProgramState *state = Ctx.getState();
|
ProgramStateRef state = Ctx.getState();
|
||||||
|
|
||||||
// Iterate over all bindings to global variables and see if it contains
|
// Iterate over all bindings to global variables and see if it contains
|
||||||
// a memory region in the stack space.
|
// a memory region in the stack space.
|
||||||
|
|
|
@ -96,9 +96,9 @@ private:
|
||||||
|
|
||||||
void OpenFileAux(CheckerContext &C, const CallExpr *CE) const;
|
void OpenFileAux(CheckerContext &C, const CallExpr *CE) const;
|
||||||
|
|
||||||
const ProgramState *CheckNullStream(SVal SV, const ProgramState *state,
|
ProgramStateRef CheckNullStream(SVal SV, ProgramStateRef state,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
const ProgramState *CheckDoubleClose(const CallExpr *CE, const ProgramState *state,
|
ProgramStateRef CheckDoubleClose(const CallExpr *CE, ProgramStateRef state,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ void StreamChecker::Tmpfile(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
unsigned Count = C.getCurrentBlockCount();
|
unsigned Count = C.getCurrentBlockCount();
|
||||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||||
DefinedSVal RetVal =
|
DefinedSVal RetVal =
|
||||||
|
@ -228,7 +228,7 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
|
||||||
ConstraintManager &CM = C.getConstraintManager();
|
ConstraintManager &CM = C.getConstraintManager();
|
||||||
// Bifurcate the state into two: one with a valid FILE* pointer, the other
|
// Bifurcate the state into two: one with a valid FILE* pointer, the other
|
||||||
// with a NULL.
|
// with a NULL.
|
||||||
const ProgramState *stateNotNull, *stateNull;
|
ProgramStateRef stateNotNull, stateNull;
|
||||||
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
|
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
|
||||||
|
|
||||||
if (SymbolRef Sym = RetVal.getAsSymbol()) {
|
if (SymbolRef Sym = RetVal.getAsSymbol()) {
|
||||||
|
@ -244,27 +244,27 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fclose(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fclose(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = CheckDoubleClose(CE, C.getState(), C);
|
ProgramStateRef state = CheckDoubleClose(CE, C.getState(), C);
|
||||||
if (state)
|
if (state)
|
||||||
C.addTransition(state);
|
C.addTransition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fread(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fread(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fwrite(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fwrite(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!(state = CheckNullStream(state->getSVal(CE->getArg(0),
|
if (!(state = CheckNullStream(state->getSVal(CE->getArg(0),
|
||||||
C.getLocationContext()), state, C)))
|
C.getLocationContext()), state, C)))
|
||||||
return;
|
return;
|
||||||
|
@ -291,69 +291,69 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Ftell(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Ftell(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Rewind(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Rewind(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fgetpos(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fgetpos(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fsetpos(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fsetpos(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Clearerr(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Clearerr(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Feof(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Feof(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Ferror(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Ferror(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) const {
|
void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
|
||||||
state, C))
|
state, C))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *StreamChecker::CheckNullStream(SVal SV, const ProgramState *state,
|
ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
|
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
|
||||||
if (!DV)
|
if (!DV)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ConstraintManager &CM = C.getConstraintManager();
|
ConstraintManager &CM = C.getConstraintManager();
|
||||||
const ProgramState *stateNotNull, *stateNull;
|
ProgramStateRef stateNotNull, stateNull;
|
||||||
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
|
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
|
||||||
|
|
||||||
if (!stateNotNull && stateNull) {
|
if (!stateNotNull && stateNull) {
|
||||||
|
@ -369,8 +369,8 @@ const ProgramState *StreamChecker::CheckNullStream(SVal SV, const ProgramState *
|
||||||
return stateNotNull;
|
return stateNotNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *StreamChecker::CheckDoubleClose(const CallExpr *CE,
|
ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
SymbolRef Sym =
|
SymbolRef Sym =
|
||||||
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsSymbol();
|
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsSymbol();
|
||||||
|
@ -408,7 +408,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
|
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
|
||||||
E = SymReaper.dead_end(); I != E; ++I) {
|
E = SymReaper.dead_end(); I != E; ++I) {
|
||||||
SymbolRef Sym = *I;
|
SymbolRef Sym = *I;
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const StreamState *SS = state->get<StreamState>(Sym);
|
const StreamState *SS = state->get<StreamState>(Sym);
|
||||||
if (!SS)
|
if (!SS)
|
||||||
return;
|
return;
|
||||||
|
@ -428,7 +428,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamChecker::checkEndPath(CheckerContext &Ctx) const {
|
void StreamChecker::checkEndPath(CheckerContext &Ctx) const {
|
||||||
const ProgramState *state = Ctx.getState();
|
ProgramStateRef state = Ctx.getState();
|
||||||
typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
|
typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
|
||||||
SymMap M = state->get<StreamState>();
|
SymMap M = state->get<StreamState>();
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ void StreamChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
|
||||||
if (!RetE)
|
if (!RetE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SymbolRef Sym = state->getSVal(RetE, C.getLocationContext()).getAsSymbol();
|
SymbolRef Sym = state->getSVal(RetE, C.getLocationContext()).getAsSymbol();
|
||||||
|
|
||||||
if (!Sym)
|
if (!Sym)
|
||||||
|
|
|
@ -43,7 +43,7 @@ inline void TaintTesterChecker::initBugType() const {
|
||||||
|
|
||||||
void TaintTesterChecker::checkPostStmt(const Expr *E,
|
void TaintTesterChecker::checkPostStmt(const Expr *E,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *State = C.getState();
|
ProgramStateRef State = C.getState();
|
||||||
if (!State)
|
if (!State)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
|
||||||
mutable llvm::OwningPtr<BuiltinBug> BT;
|
mutable llvm::OwningPtr<BuiltinBug> BT;
|
||||||
|
|
||||||
struct FindUndefExpr {
|
struct FindUndefExpr {
|
||||||
const ProgramState *St;
|
ProgramStateRef St;
|
||||||
const LocationContext *LCtx;
|
const LocationContext *LCtx;
|
||||||
|
|
||||||
FindUndefExpr(const ProgramState *S, const LocationContext *L)
|
FindUndefExpr(ProgramStateRef S, const LocationContext *L)
|
||||||
: St(S), LCtx(L) {}
|
: St(S), LCtx(L) {}
|
||||||
|
|
||||||
const Expr *FindExpr(const Expr *Ex) {
|
const Expr *FindExpr(const Expr *Ex) {
|
||||||
|
@ -88,7 +88,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
|
||||||
const Expr *Ex = cast<Expr>(Condition);
|
const Expr *Ex = cast<Expr>(Condition);
|
||||||
ExplodedNode *PrevN = *N->pred_begin();
|
ExplodedNode *PrevN = *N->pred_begin();
|
||||||
ProgramPoint P = PrevN->getLocation();
|
ProgramPoint P = PrevN->getLocation();
|
||||||
const ProgramState *St = N->getState();
|
ProgramStateRef St = N->getState();
|
||||||
|
|
||||||
if (PostStmt *PS = dyn_cast<PostStmt>(&P))
|
if (PostStmt *PS = dyn_cast<PostStmt>(&P))
|
||||||
if (PS->getStmt() == Ex)
|
if (PS->getStmt() == Ex)
|
||||||
|
|
|
@ -55,7 +55,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
|
||||||
if (!BE->getBlockDecl()->hasCaptures())
|
if (!BE->getBlockDecl()->hasCaptures())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const BlockDataRegion *R =
|
const BlockDataRegion *R =
|
||||||
cast<BlockDataRegion>(state->getSVal(BE,
|
cast<BlockDataRegion>(state->getSVal(BE,
|
||||||
C.getLocationContext()).getAsRegion());
|
C.getLocationContext()).getAsRegion());
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
|
void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const LocationContext *LCtx = C.getLocationContext();
|
const LocationContext *LCtx = C.getLocationContext();
|
||||||
if (state->getSVal(B, LCtx).isUndef()) {
|
if (state->getSVal(B, LCtx).isUndef()) {
|
||||||
// Generate an error node.
|
// Generate an error node.
|
||||||
|
|
|
@ -54,7 +54,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
|
||||||
while (StoreE) {
|
while (StoreE) {
|
||||||
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
|
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
|
||||||
if (B->isCompoundAssignmentOp()) {
|
if (B->isCompoundAssignmentOp()) {
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) {
|
if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) {
|
||||||
str = "The left expression of the compound assignment is an "
|
str = "The left expression of the compound assignment is an "
|
||||||
"uninitialized value. The computed value will also be garbage";
|
"uninitialized value. The computed value will also be garbage";
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
const CallExpr *) const;
|
const CallExpr *) const;
|
||||||
private:
|
private:
|
||||||
bool ReportZeroByteAllocation(CheckerContext &C,
|
bool ReportZeroByteAllocation(CheckerContext &C,
|
||||||
const ProgramState *falseState,
|
ProgramStateRef falseState,
|
||||||
const Expr *arg,
|
const Expr *arg,
|
||||||
const char *fn_name) const;
|
const char *fn_name) const;
|
||||||
void BasicAllocationCheck(CheckerContext &C,
|
void BasicAllocationCheck(CheckerContext &C,
|
||||||
|
@ -88,7 +88,7 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look at the 'oflags' argument for the O_CREAT flag.
|
// Look at the 'oflags' argument for the O_CREAT flag.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
|
|
||||||
if (CE->getNumArgs() < 2) {
|
if (CE->getNumArgs() < 2) {
|
||||||
// The frontend should issue a warning for this case, so this is a sanity
|
// The frontend should issue a warning for this case, so this is a sanity
|
||||||
|
@ -116,7 +116,7 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
|
||||||
DefinedSVal maskedFlags = cast<DefinedSVal>(maskedFlagsUC);
|
DefinedSVal maskedFlags = cast<DefinedSVal>(maskedFlagsUC);
|
||||||
|
|
||||||
// Check if maskedFlags is non-zero.
|
// Check if maskedFlags is non-zero.
|
||||||
const ProgramState *trueState, *falseState;
|
ProgramStateRef trueState, falseState;
|
||||||
llvm::tie(trueState, falseState) = state->assume(maskedFlags);
|
llvm::tie(trueState, falseState) = state->assume(maskedFlags);
|
||||||
|
|
||||||
// Only emit an error if the value of 'maskedFlags' is properly
|
// Only emit an error if the value of 'maskedFlags' is properly
|
||||||
|
@ -155,7 +155,7 @@ void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
|
||||||
|
|
||||||
// Check if the first argument is stack allocated. If so, issue a warning
|
// Check if the first argument is stack allocated. If so, issue a warning
|
||||||
// because that's likely to be bad news.
|
// because that's likely to be bad news.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const MemRegion *R =
|
const MemRegion *R =
|
||||||
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
|
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
|
||||||
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
|
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
|
||||||
|
@ -192,10 +192,10 @@ void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
|
||||||
|
|
||||||
// Returns true if we try to do a zero byte allocation, false otherwise.
|
// Returns true if we try to do a zero byte allocation, false otherwise.
|
||||||
// Fills in trueState and falseState.
|
// Fills in trueState and falseState.
|
||||||
static bool IsZeroByteAllocation(const ProgramState *state,
|
static bool IsZeroByteAllocation(ProgramStateRef state,
|
||||||
const SVal argVal,
|
const SVal argVal,
|
||||||
const ProgramState **trueState,
|
ProgramStateRef *trueState,
|
||||||
const ProgramState **falseState) {
|
ProgramStateRef *falseState) {
|
||||||
llvm::tie(*trueState, *falseState) =
|
llvm::tie(*trueState, *falseState) =
|
||||||
state->assume(cast<DefinedSVal>(argVal));
|
state->assume(cast<DefinedSVal>(argVal));
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ static bool IsZeroByteAllocation(const ProgramState *state,
|
||||||
// will perform a zero byte allocation.
|
// will perform a zero byte allocation.
|
||||||
// Returns false if an error occured, true otherwise.
|
// Returns false if an error occured, true otherwise.
|
||||||
bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
|
bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
|
||||||
const ProgramState *falseState,
|
ProgramStateRef falseState,
|
||||||
const Expr *arg,
|
const Expr *arg,
|
||||||
const char *fn_name) const {
|
const char *fn_name) const {
|
||||||
ExplodedNode *N = C.generateSink(falseState);
|
ExplodedNode *N = C.generateSink(falseState);
|
||||||
|
@ -240,8 +240,8 @@ void UnixAPIChecker::BasicAllocationCheck(CheckerContext &C,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if the allocation size is 0.
|
// Check if the allocation size is 0.
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const ProgramState *trueState = NULL, *falseState = NULL;
|
ProgramStateRef trueState = NULL, falseState = NULL;
|
||||||
const Expr *arg = CE->getArg(sizeArg);
|
const Expr *arg = CE->getArg(sizeArg);
|
||||||
SVal argVal = state->getSVal(arg, C.getLocationContext());
|
SVal argVal = state->getSVal(arg, C.getLocationContext());
|
||||||
|
|
||||||
|
@ -265,8 +265,8 @@ void UnixAPIChecker::CheckCallocZero(CheckerContext &C,
|
||||||
if (nArgs != 2)
|
if (nArgs != 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
const ProgramState *trueState = NULL, *falseState = NULL;
|
ProgramStateRef trueState = NULL, falseState = NULL;
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < nArgs; i++) {
|
for (i = 0; i < nArgs; i++) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ class VLASizeChecker : public Checker< check::PreStmt<DeclStmt> > {
|
||||||
|
|
||||||
void reportBug(VLASize_Kind Kind,
|
void reportBug(VLASize_Kind Kind,
|
||||||
const Expr *SizeE,
|
const Expr *SizeE,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
CheckerContext &C) const;
|
CheckerContext &C) const;
|
||||||
public:
|
public:
|
||||||
void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
|
void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
void VLASizeChecker::reportBug(VLASize_Kind Kind,
|
void VLASizeChecker::reportBug(VLASize_Kind Kind,
|
||||||
const Expr *SizeE,
|
const Expr *SizeE,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
CheckerContext &C) const {
|
CheckerContext &C) const {
|
||||||
// Generate an error node.
|
// Generate an error node.
|
||||||
ExplodedNode *N = C.generateSink(State);
|
ExplodedNode *N = C.generateSink(State);
|
||||||
|
@ -87,7 +87,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
||||||
|
|
||||||
// FIXME: Handle multi-dimensional VLAs.
|
// FIXME: Handle multi-dimensional VLAs.
|
||||||
const Expr *SE = VLA->getSizeExpr();
|
const Expr *SE = VLA->getSizeExpr();
|
||||||
const ProgramState *state = C.getState();
|
ProgramStateRef state = C.getState();
|
||||||
SVal sizeV = state->getSVal(SE, C.getLocationContext());
|
SVal sizeV = state->getSVal(SE, C.getLocationContext());
|
||||||
|
|
||||||
if (sizeV.isUndef()) {
|
if (sizeV.isUndef()) {
|
||||||
|
@ -109,7 +109,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
||||||
// Check if the size is zero.
|
// Check if the size is zero.
|
||||||
DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
|
DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
|
||||||
|
|
||||||
const ProgramState *stateNotZero, *stateZero;
|
ProgramStateRef stateNotZero, stateZero;
|
||||||
llvm::tie(stateNotZero, stateZero) = state->assume(sizeD);
|
llvm::tie(stateNotZero, stateZero) = state->assume(sizeD);
|
||||||
|
|
||||||
if (stateZero && !stateNotZero) {
|
if (stateZero && !stateNotZero) {
|
||||||
|
|
|
@ -56,59 +56,59 @@ public:
|
||||||
: SimpleConstraintManager(subengine),
|
: SimpleConstraintManager(subengine),
|
||||||
ISetFactory(statemgr.getAllocator()) {}
|
ISetFactory(statemgr.getAllocator()) {}
|
||||||
|
|
||||||
const ProgramState *assumeSymNE(const ProgramState *state,
|
ProgramStateRef assumeSymNE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymEQ(const ProgramState *state,
|
ProgramStateRef assumeSymEQ(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymLT(const ProgramState *state,
|
ProgramStateRef assumeSymLT(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymGT(const ProgramState *state,
|
ProgramStateRef assumeSymGT(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymGE(const ProgramState *state,
|
ProgramStateRef assumeSymGE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymLE(const ProgramState *state,
|
ProgramStateRef assumeSymLE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *AddEQ(const ProgramState *state,
|
ProgramStateRef AddEQ(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V);
|
const llvm::APSInt& V);
|
||||||
|
|
||||||
const ProgramState *AddNE(const ProgramState *state,
|
ProgramStateRef AddNE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V);
|
const llvm::APSInt& V);
|
||||||
|
|
||||||
const llvm::APSInt* getSymVal(const ProgramState *state,
|
const llvm::APSInt* getSymVal(ProgramStateRef state,
|
||||||
SymbolRef sym) const;
|
SymbolRef sym) const;
|
||||||
|
|
||||||
bool isNotEqual(const ProgramState *state,
|
bool isNotEqual(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) const;
|
const llvm::APSInt& V) const;
|
||||||
|
|
||||||
bool isEqual(const ProgramState *state,
|
bool isEqual(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) const;
|
const llvm::APSInt& V) const;
|
||||||
|
|
||||||
const ProgramState *removeDeadBindings(const ProgramState *state,
|
ProgramStateRef removeDeadBindings(ProgramStateRef state,
|
||||||
SymbolReaper& SymReaper);
|
SymbolReaper& SymReaper);
|
||||||
|
|
||||||
void print(const ProgramState *state,
|
void print(ProgramStateRef state,
|
||||||
raw_ostream &Out,
|
raw_ostream &Out,
|
||||||
const char* nl,
|
const char* nl,
|
||||||
const char *sep);
|
const char *sep);
|
||||||
|
@ -122,8 +122,8 @@ ento::CreateBasicConstraintManager(ProgramStateManager& statemgr,
|
||||||
return new BasicConstraintManager(statemgr, subengine);
|
return new BasicConstraintManager(statemgr, subengine);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymNE(const ProgramState *state,
|
BasicConstraintManager::assumeSymNE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -143,8 +143,8 @@ BasicConstraintManager::assumeSymNE(const ProgramState *state,
|
||||||
return AddNE(state, sym, Adjusted);
|
return AddNE(state, sym, Adjusted);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymEQ(const ProgramState *state,
|
BasicConstraintManager::assumeSymEQ(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -165,8 +165,8 @@ BasicConstraintManager::assumeSymEQ(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The logic for these will be handled in another ConstraintManager.
|
// The logic for these will be handled in another ConstraintManager.
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymLT(const ProgramState *state,
|
BasicConstraintManager::assumeSymLT(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -180,8 +180,8 @@ BasicConstraintManager::assumeSymLT(const ProgramState *state,
|
||||||
return assumeSymNE(state, sym, V, Adjustment);
|
return assumeSymNE(state, sym, V, Adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymGT(const ProgramState *state,
|
BasicConstraintManager::assumeSymGT(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -195,8 +195,8 @@ BasicConstraintManager::assumeSymGT(const ProgramState *state,
|
||||||
return assumeSymNE(state, sym, V, Adjustment);
|
return assumeSymNE(state, sym, V, Adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymGE(const ProgramState *state,
|
BasicConstraintManager::assumeSymGE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -224,8 +224,8 @@ BasicConstraintManager::assumeSymGE(const ProgramState *state,
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::assumeSymLE(const ProgramState *state,
|
BasicConstraintManager::assumeSymLE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt &V,
|
const llvm::APSInt &V,
|
||||||
const llvm::APSInt &Adjustment) {
|
const llvm::APSInt &Adjustment) {
|
||||||
|
@ -253,14 +253,14 @@ BasicConstraintManager::assumeSymLE(const ProgramState *state,
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *BasicConstraintManager::AddEQ(const ProgramState *state,
|
ProgramStateRef BasicConstraintManager::AddEQ(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) {
|
const llvm::APSInt& V) {
|
||||||
// Create a new state with the old binding replaced.
|
// Create a new state with the old binding replaced.
|
||||||
return state->set<ConstEq>(sym, &state->getBasicVals().getValue(V));
|
return state->set<ConstEq>(sym, &state->getBasicVals().getValue(V));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *BasicConstraintManager::AddNE(const ProgramState *state,
|
ProgramStateRef BasicConstraintManager::AddNE(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) {
|
const llvm::APSInt& V) {
|
||||||
|
|
||||||
|
@ -275,13 +275,13 @@ const ProgramState *BasicConstraintManager::AddNE(const ProgramState *state,
|
||||||
return state->set<ConstNotEq>(sym, S);
|
return state->set<ConstNotEq>(sym, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::APSInt* BasicConstraintManager::getSymVal(const ProgramState *state,
|
const llvm::APSInt* BasicConstraintManager::getSymVal(ProgramStateRef state,
|
||||||
SymbolRef sym) const {
|
SymbolRef sym) const {
|
||||||
const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
|
const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
|
||||||
return T ? *T : NULL;
|
return T ? *T : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BasicConstraintManager::isNotEqual(const ProgramState *state,
|
bool BasicConstraintManager::isNotEqual(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) const {
|
const llvm::APSInt& V) const {
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ bool BasicConstraintManager::isNotEqual(const ProgramState *state,
|
||||||
return T ? T->contains(&state->getBasicVals().getValue(V)) : false;
|
return T ? T->contains(&state->getBasicVals().getValue(V)) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BasicConstraintManager::isEqual(const ProgramState *state,
|
bool BasicConstraintManager::isEqual(ProgramStateRef state,
|
||||||
SymbolRef sym,
|
SymbolRef sym,
|
||||||
const llvm::APSInt& V) const {
|
const llvm::APSInt& V) const {
|
||||||
// Retrieve the EQ-set associated with the given symbol.
|
// Retrieve the EQ-set associated with the given symbol.
|
||||||
|
@ -303,8 +303,8 @@ bool BasicConstraintManager::isEqual(const ProgramState *state,
|
||||||
|
|
||||||
/// Scan all symbols referenced by the constraints. If the symbol is not alive
|
/// Scan all symbols referenced by the constraints. If the symbol is not alive
|
||||||
/// as marked in LSymbols, mark it as dead in DSymbols.
|
/// as marked in LSymbols, mark it as dead in DSymbols.
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
BasicConstraintManager::removeDeadBindings(const ProgramState *state,
|
BasicConstraintManager::removeDeadBindings(ProgramStateRef state,
|
||||||
SymbolReaper& SymReaper) {
|
SymbolReaper& SymReaper) {
|
||||||
|
|
||||||
ConstEqTy CE = state->get<ConstEq>();
|
ConstEqTy CE = state->get<ConstEq>();
|
||||||
|
@ -329,7 +329,7 @@ BasicConstraintManager::removeDeadBindings(const ProgramState *state,
|
||||||
return state->set<ConstNotEq>(CNE);
|
return state->set<ConstNotEq>(CNE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicConstraintManager::print(const ProgramState *state,
|
void BasicConstraintManager::print(ProgramStateRef state,
|
||||||
raw_ostream &Out,
|
raw_ostream &Out,
|
||||||
const char* nl, const char *sep) {
|
const char* nl, const char *sep) {
|
||||||
// Print equality constraints.
|
// Print equality constraints.
|
||||||
|
|
|
@ -364,7 +364,7 @@ class NotableSymbolHandler
|
||||||
: public StoreManager::BindingsHandler {
|
: public StoreManager::BindingsHandler {
|
||||||
|
|
||||||
SymbolRef Sym;
|
SymbolRef Sym;
|
||||||
const ProgramState *PrevSt;
|
ProgramStateRef PrevSt;
|
||||||
const Stmt *S;
|
const Stmt *S;
|
||||||
ProgramStateManager& VMgr;
|
ProgramStateManager& VMgr;
|
||||||
const ExplodedNode *Pred;
|
const ExplodedNode *Pred;
|
||||||
|
@ -374,7 +374,7 @@ class NotableSymbolHandler
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NotableSymbolHandler(SymbolRef sym,
|
NotableSymbolHandler(SymbolRef sym,
|
||||||
const ProgramState *prevst,
|
ProgramStateRef prevst,
|
||||||
const Stmt *s,
|
const Stmt *s,
|
||||||
ProgramStateManager& vmgr,
|
ProgramStateManager& vmgr,
|
||||||
const ExplodedNode *pred,
|
const ExplodedNode *pred,
|
||||||
|
@ -458,7 +458,7 @@ static void HandleNotableSymbol(const ExplodedNode *N,
|
||||||
PathDiagnostic& PD) {
|
PathDiagnostic& PD) {
|
||||||
|
|
||||||
const ExplodedNode *Pred = N->pred_empty() ? 0 : *N->pred_begin();
|
const ExplodedNode *Pred = N->pred_empty() ? 0 : *N->pred_begin();
|
||||||
const ProgramState *PrevSt = Pred ? Pred->getState() : 0;
|
ProgramStateRef PrevSt = Pred ? Pred->getState() : 0;
|
||||||
|
|
||||||
if (!PrevSt)
|
if (!PrevSt)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -324,7 +324,7 @@ bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
|
||||||
if (!N)
|
if (!N)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
|
|
||||||
// Walk through lvalue-to-rvalue conversions.
|
// Walk through lvalue-to-rvalue conversions.
|
||||||
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
|
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
|
||||||
|
@ -369,7 +369,7 @@ FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
|
||||||
const MemRegion *R) {
|
const MemRegion *R) {
|
||||||
assert(R && "The memory region is null.");
|
assert(R && "The memory region is null.");
|
||||||
|
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
SVal V = state->getSVal(R);
|
SVal V = state->getSVal(R);
|
||||||
if (V.isUnknown())
|
if (V.isUnknown())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -391,7 +391,7 @@ PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
|
||||||
const Expr *Receiver = ME->getInstanceReceiver();
|
const Expr *Receiver = ME->getInstanceReceiver();
|
||||||
if (!Receiver)
|
if (!Receiver)
|
||||||
return 0;
|
return 0;
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
const SVal &V = state->getSVal(Receiver, N->getLocationContext());
|
const SVal &V = state->getSVal(Receiver, N->getLocationContext());
|
||||||
const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
|
const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
|
||||||
if (!DV)
|
if (!DV)
|
||||||
|
@ -422,7 +422,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
|
||||||
const Stmt *Head = WorkList.front();
|
const Stmt *Head = WorkList.front();
|
||||||
WorkList.pop_front();
|
WorkList.pop_front();
|
||||||
|
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
ProgramStateManager &StateMgr = state->getStateManager();
|
ProgramStateManager &StateMgr = state->getStateManager();
|
||||||
|
|
||||||
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
|
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
|
||||||
|
@ -456,8 +456,8 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
|
||||||
|
|
||||||
const ProgramPoint &progPoint = N->getLocation();
|
const ProgramPoint &progPoint = N->getLocation();
|
||||||
|
|
||||||
const ProgramState *CurrentState = N->getState();
|
ProgramStateRef CurrentState = N->getState();
|
||||||
const ProgramState *PrevState = Prev->getState();
|
ProgramStateRef PrevState = Prev->getState();
|
||||||
|
|
||||||
// Compare the GDMs of the state, because that is where constraints
|
// Compare the GDMs of the state, because that is where constraints
|
||||||
// are managed. Note that ensure that we only look at nodes that
|
// are managed. Note that ensure that we only look at nodes that
|
||||||
|
|
|
@ -20,7 +20,7 @@ using namespace clang;
|
||||||
using namespace ento;
|
using namespace ento;
|
||||||
|
|
||||||
const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
|
const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
|
||||||
const ProgramState *State = getState();
|
ProgramStateRef State = getState();
|
||||||
const Expr *Callee = CE->getCallee();
|
const Expr *Callee = CE->getCallee();
|
||||||
SVal L = State->getSVal(Callee, Pred->getLocationContext());
|
SVal L = State->getSVal(Callee, Pred->getLocationContext());
|
||||||
return L.getAsFunctionDecl();
|
return L.getAsFunctionDecl();
|
||||||
|
|
|
@ -356,7 +356,7 @@ void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Run checkers for live symbols.
|
/// \brief Run checkers for live symbols.
|
||||||
void CheckerManager::runCheckersForLiveSymbols(const ProgramState *state,
|
void CheckerManager::runCheckersForLiveSymbols(ProgramStateRef state,
|
||||||
SymbolReaper &SymReaper) {
|
SymbolReaper &SymReaper) {
|
||||||
for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i)
|
for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i)
|
||||||
LiveSymbolsCheckers[i](state, SymReaper);
|
LiveSymbolsCheckers[i](state, SymReaper);
|
||||||
|
@ -400,7 +400,7 @@ void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief True if at least one checker wants to check region changes.
|
/// \brief True if at least one checker wants to check region changes.
|
||||||
bool CheckerManager::wantsRegionChangeUpdate(const ProgramState *state) {
|
bool CheckerManager::wantsRegionChangeUpdate(ProgramStateRef state) {
|
||||||
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i)
|
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i)
|
||||||
if (RegionChangesCheckers[i].WantUpdateFn(state))
|
if (RegionChangesCheckers[i].WantUpdateFn(state))
|
||||||
return true;
|
return true;
|
||||||
|
@ -409,8 +409,8 @@ bool CheckerManager::wantsRegionChangeUpdate(const ProgramState *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Run checkers for region changes.
|
/// \brief Run checkers for region changes.
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
CheckerManager::runCheckersForRegionChanges(const ProgramState *state,
|
CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> ExplicitRegions,
|
ArrayRef<const MemRegion *> ExplicitRegions,
|
||||||
ArrayRef<const MemRegion *> Regions) {
|
ArrayRef<const MemRegion *> Regions) {
|
||||||
|
@ -426,8 +426,8 @@ CheckerManager::runCheckersForRegionChanges(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Run checkers for handling assumptions on symbolic values.
|
/// \brief Run checkers for handling assumptions on symbolic values.
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
CheckerManager::runCheckersForEvalAssume(const ProgramState *state,
|
CheckerManager::runCheckersForEvalAssume(ProgramStateRef state,
|
||||||
SVal Cond, bool Assumption) {
|
SVal Cond, bool Assumption) {
|
||||||
for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) {
|
for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) {
|
||||||
// If any checker declares the state infeasible (or if it starts that way),
|
// If any checker declares the state infeasible (or if it starts that way),
|
||||||
|
@ -534,7 +534,7 @@ void CheckerManager::runCheckersOnEndOfTranslationUnit(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerManager::runCheckersForPrintState(raw_ostream &Out,
|
void CheckerManager::runCheckersForPrintState(raw_ostream &Out,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
const char *NL, const char *Sep) {
|
const char *NL, const char *Sep) {
|
||||||
for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator
|
for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator
|
||||||
I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I)
|
I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I)
|
||||||
|
|
|
@ -152,7 +152,7 @@ WorkList* WorkList::makeBFSBlockDFSContents() {
|
||||||
|
|
||||||
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
|
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
|
||||||
bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
|
bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
|
||||||
const ProgramState *InitState) {
|
ProgramStateRef InitState) {
|
||||||
|
|
||||||
if (G->num_roots() == 0) { // Initialize the analysis by constructing
|
if (G->num_roots() == 0) { // Initialize the analysis by constructing
|
||||||
// the root if none exists.
|
// the root if none exists.
|
||||||
|
@ -236,7 +236,7 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
|
||||||
|
|
||||||
void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
|
void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
|
||||||
unsigned Steps,
|
unsigned Steps,
|
||||||
const ProgramState *InitState,
|
ProgramStateRef InitState,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
ExecuteWorkList(L, Steps, InitState);
|
ExecuteWorkList(L, Steps, InitState);
|
||||||
for (SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(),
|
for (SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(),
|
||||||
|
@ -424,7 +424,7 @@ void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
|
||||||
/// generateNode - Utility method to generate nodes, hook up successors,
|
/// generateNode - Utility method to generate nodes, hook up successors,
|
||||||
/// and add nodes to the worklist.
|
/// and add nodes to the worklist.
|
||||||
void CoreEngine::generateNode(const ProgramPoint &Loc,
|
void CoreEngine::generateNode(const ProgramPoint &Loc,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
ExplodedNode *Pred) {
|
ExplodedNode *Pred) {
|
||||||
|
|
||||||
bool IsNew;
|
bool IsNew;
|
||||||
|
@ -527,7 +527,7 @@ void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set) {
|
||||||
void NodeBuilder::anchor() { }
|
void NodeBuilder::anchor() { }
|
||||||
|
|
||||||
ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
|
ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
ExplodedNode *FromN,
|
ExplodedNode *FromN,
|
||||||
bool MarkAsSink) {
|
bool MarkAsSink) {
|
||||||
HasGeneratedNodes = true;
|
HasGeneratedNodes = true;
|
||||||
|
@ -556,7 +556,7 @@ StmtNodeBuilder::~StmtNodeBuilder() {
|
||||||
|
|
||||||
void BranchNodeBuilder::anchor() { }
|
void BranchNodeBuilder::anchor() { }
|
||||||
|
|
||||||
ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
|
ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State,
|
||||||
bool branch,
|
bool branch,
|
||||||
ExplodedNode *NodePred) {
|
ExplodedNode *NodePred) {
|
||||||
// If the branch has been marked infeasible we should not generate a node.
|
// If the branch has been marked infeasible we should not generate a node.
|
||||||
|
@ -571,7 +571,7 @@ ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
|
||||||
|
|
||||||
ExplodedNode*
|
ExplodedNode*
|
||||||
IndirectGotoNodeBuilder::generateNode(const iterator &I,
|
IndirectGotoNodeBuilder::generateNode(const iterator &I,
|
||||||
const ProgramState *St,
|
ProgramStateRef St,
|
||||||
bool IsSink) {
|
bool IsSink) {
|
||||||
bool IsNew;
|
bool IsNew;
|
||||||
ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
|
ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
|
||||||
|
@ -591,7 +591,7 @@ IndirectGotoNodeBuilder::generateNode(const iterator &I,
|
||||||
|
|
||||||
ExplodedNode*
|
ExplodedNode*
|
||||||
SwitchNodeBuilder::generateCaseStmtNode(const iterator &I,
|
SwitchNodeBuilder::generateCaseStmtNode(const iterator &I,
|
||||||
const ProgramState *St) {
|
ProgramStateRef St) {
|
||||||
|
|
||||||
bool IsNew;
|
bool IsNew;
|
||||||
ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
|
ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
|
||||||
|
@ -607,7 +607,7 @@ SwitchNodeBuilder::generateCaseStmtNode(const iterator &I,
|
||||||
|
|
||||||
|
|
||||||
ExplodedNode*
|
ExplodedNode*
|
||||||
SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St,
|
SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St,
|
||||||
bool IsSink) {
|
bool IsSink) {
|
||||||
// Get the block for the default case.
|
// Get the block for the default case.
|
||||||
assert(Src->succ_rbegin() != Src->succ_rend());
|
assert(Src->succ_rbegin() != Src->succ_rend());
|
||||||
|
|
|
@ -160,7 +160,7 @@ static inline bool IsLocation(const EnvironmentEntry &E) {
|
||||||
Environment
|
Environment
|
||||||
EnvironmentManager::removeDeadBindings(Environment Env,
|
EnvironmentManager::removeDeadBindings(Environment Env,
|
||||||
SymbolReaper &SymReaper,
|
SymbolReaper &SymReaper,
|
||||||
const ProgramState *ST) {
|
ProgramStateRef ST) {
|
||||||
|
|
||||||
// We construct a new Environment object entirely, as this is cheaper than
|
// We construct a new Environment object entirely, as this is cheaper than
|
||||||
// individually removing all the subexpression bindings (which will greatly
|
// individually removing all the subexpression bindings (which will greatly
|
||||||
|
|
|
@ -120,8 +120,8 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Conditions 5, 6, and 7.
|
// Conditions 5, 6, and 7.
|
||||||
const ProgramState *state = node->getState();
|
ProgramStateRef state = node->getState();
|
||||||
const ProgramState *pred_state = pred->getState();
|
ProgramStateRef pred_state = pred->getState();
|
||||||
if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
|
if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
|
||||||
progPoint.getLocationContext() != pred->getLocationContext())
|
progPoint.getLocationContext() != pred->getLocationContext())
|
||||||
continue;
|
continue;
|
||||||
|
@ -236,7 +236,7 @@ ExplodedNode** ExplodedNode::NodeGroup::end() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
|
ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
bool IsSink,
|
bool IsSink,
|
||||||
bool* IsNew) {
|
bool* IsNew) {
|
||||||
// Profile 'State' to determine if we already have an existing node.
|
// Profile 'State' to determine if we already have an existing node.
|
||||||
|
|
|
@ -80,8 +80,8 @@ ExprEngine::~ExprEngine() {
|
||||||
// Utility methods.
|
// Utility methods.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc) {
|
ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
|
||||||
const ProgramState *state = StateMgr.getInitialState(InitLoc);
|
ProgramStateRef state = StateMgr.getInitialState(InitLoc);
|
||||||
const Decl *D = InitLoc->getDecl();
|
const Decl *D = InitLoc->getDecl();
|
||||||
|
|
||||||
// Preconditions.
|
// Preconditions.
|
||||||
|
@ -116,7 +116,7 @@ const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc)
|
||||||
if (!Constraint)
|
if (!Constraint)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (const ProgramState *newState = state->assume(*Constraint, true))
|
if (ProgramStateRef newState = state->assume(*Constraint, true))
|
||||||
state = newState;
|
state = newState;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -163,17 +163,17 @@ const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc)
|
||||||
|
|
||||||
/// evalAssume - Called by ConstraintManager. Used to call checker-specific
|
/// evalAssume - Called by ConstraintManager. Used to call checker-specific
|
||||||
/// logic for handling assumptions on symbolic values.
|
/// logic for handling assumptions on symbolic values.
|
||||||
const ProgramState *ExprEngine::processAssume(const ProgramState *state,
|
ProgramStateRef ExprEngine::processAssume(ProgramStateRef state,
|
||||||
SVal cond, bool assumption) {
|
SVal cond, bool assumption) {
|
||||||
return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
|
return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExprEngine::wantsRegionChangeUpdate(const ProgramState *state) {
|
bool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) {
|
||||||
return getCheckerManager().wantsRegionChangeUpdate(state);
|
return getCheckerManager().wantsRegionChangeUpdate(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ExprEngine::processRegionChanges(const ProgramState *state,
|
ExprEngine::processRegionChanges(ProgramStateRef state,
|
||||||
const StoreManager::InvalidatedSymbols *invalidated,
|
const StoreManager::InvalidatedSymbols *invalidated,
|
||||||
ArrayRef<const MemRegion *> Explicits,
|
ArrayRef<const MemRegion *> Explicits,
|
||||||
ArrayRef<const MemRegion *> Regions) {
|
ArrayRef<const MemRegion *> Regions) {
|
||||||
|
@ -181,7 +181,7 @@ ExprEngine::processRegionChanges(const ProgramState *state,
|
||||||
Explicits, Regions);
|
Explicits, Regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprEngine::printState(raw_ostream &Out, const ProgramState *State,
|
void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
|
||||||
const char *NL, const char *Sep) {
|
const char *NL, const char *Sep) {
|
||||||
getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
|
getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S,
|
||||||
|
|
||||||
EntryNode = Pred;
|
EntryNode = Pred;
|
||||||
|
|
||||||
const ProgramState *EntryState = EntryNode->getState();
|
ProgramStateRef EntryState = EntryNode->getState();
|
||||||
CleanedState = EntryState;
|
CleanedState = EntryState;
|
||||||
|
|
||||||
// Create the cleaned state.
|
// Create the cleaned state.
|
||||||
|
@ -296,7 +296,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S,
|
||||||
StmtNodeBuilder Bldr(CheckedSet, Tmp, *currentBuilderContext);
|
StmtNodeBuilder Bldr(CheckedSet, Tmp, *currentBuilderContext);
|
||||||
for (ExplodedNodeSet::const_iterator
|
for (ExplodedNodeSet::const_iterator
|
||||||
I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
|
I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
|
||||||
const ProgramState *CheckerState = (*I)->getState();
|
ProgramStateRef CheckerState = (*I)->getState();
|
||||||
|
|
||||||
// The constraint manager has not been cleaned up yet, so clean up now.
|
// The constraint manager has not been cleaned up yet, so clean up now.
|
||||||
CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
|
CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
|
||||||
|
@ -311,7 +311,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S,
|
||||||
|
|
||||||
// Create a state based on CleanedState with CheckerState GDM and
|
// Create a state based on CleanedState with CheckerState GDM and
|
||||||
// generate a transition to that state.
|
// generate a transition to that state.
|
||||||
const ProgramState *CleanedCheckerSt =
|
ProgramStateRef CleanedCheckerSt =
|
||||||
StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
|
StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
|
||||||
Bldr.generateNode(currentStmt, *I, CleanedCheckerSt, false, &cleanupTag,
|
Bldr.generateNode(currentStmt, *I, CleanedCheckerSt, false, &cleanupTag,
|
||||||
ProgramPoint::PostPurgeDeadSymbolsKind);
|
ProgramPoint::PostPurgeDeadSymbolsKind);
|
||||||
|
@ -359,7 +359,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
|
||||||
for (ExplodedNodeSet::iterator I = AfterEval.begin(),
|
for (ExplodedNodeSet::iterator I = AfterEval.begin(),
|
||||||
E = AfterEval.end(); I != E; ++I){
|
E = AfterEval.end(); I != E; ++I){
|
||||||
ExplodedNode *P = *I;
|
ExplodedNode *P = *I;
|
||||||
const ProgramState *state = P->getState();
|
ProgramStateRef state = P->getState();
|
||||||
|
|
||||||
const FieldDecl *FD = BMI->getAnyMember();
|
const FieldDecl *FD = BMI->getAnyMember();
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
|
||||||
void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
|
void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const VarDecl *varDecl = Dtor.getVarDecl();
|
const VarDecl *varDecl = Dtor.getVarDecl();
|
||||||
|
|
||||||
QualType varType = varDecl->getType();
|
QualType varType = varDecl->getType();
|
||||||
|
@ -530,7 +530,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
|
|
||||||
case Stmt::GNUNullExprClass: {
|
case Stmt::GNUNullExprClass: {
|
||||||
// GNU __null is a pointer-width integer, not an actual pointer.
|
// GNU __null is a pointer-width integer, not an actual pointer.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
state = state->BindExpr(S, Pred->getLocationContext(),
|
state = state->BindExpr(S, Pred->getLocationContext(),
|
||||||
svalBuilder.makeIntValWithPtrWidth(0, false));
|
svalBuilder.makeIntValWithPtrWidth(0, false));
|
||||||
Bldr.generateNode(S, Pred, state);
|
Bldr.generateNode(S, Pred, state);
|
||||||
|
@ -548,7 +548,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Stmt::ImplicitValueInitExprClass: {
|
case Stmt::ImplicitValueInitExprClass: {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
QualType ty = cast<ImplicitValueInitExpr>(S)->getType();
|
QualType ty = cast<ImplicitValueInitExpr>(S)->getType();
|
||||||
SVal val = svalBuilder.makeZeroVal(ty);
|
SVal val = svalBuilder.makeZeroVal(ty);
|
||||||
Bldr.generateNode(S, Pred, state->BindExpr(S, Pred->getLocationContext(),
|
Bldr.generateNode(S, Pred, state->BindExpr(S, Pred->getLocationContext(),
|
||||||
|
@ -632,7 +632,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (B->getOpcode() == BO_Comma) {
|
else if (B->getOpcode() == BO_Comma) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
Bldr.generateNode(B, Pred,
|
Bldr.generateNode(B, Pred,
|
||||||
state->BindExpr(B, Pred->getLocationContext(),
|
state->BindExpr(B, Pred->getLocationContext(),
|
||||||
state->getSVal(B->getRHS(),
|
state->getSVal(B->getRHS(),
|
||||||
|
@ -849,7 +849,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
|
if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
Bldr.generateNode(SE, Pred,
|
Bldr.generateNode(SE, Pred,
|
||||||
state->BindExpr(SE, Pred->getLocationContext(),
|
state->BindExpr(SE, Pred->getLocationContext(),
|
||||||
state->getSVal(LastExpr,
|
state->getSVal(LastExpr,
|
||||||
|
@ -859,7 +859,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
}
|
}
|
||||||
|
|
||||||
case Stmt::StringLiteralClass: {
|
case Stmt::StringLiteralClass: {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal V = state->getLValue(cast<StringLiteral>(S));
|
SVal V = state->getLValue(cast<StringLiteral>(S));
|
||||||
Bldr.generateNode(S, Pred, state->BindExpr(S, Pred->getLocationContext(),
|
Bldr.generateNode(S, Pred, state->BindExpr(S, Pred->getLocationContext(),
|
||||||
V));
|
V));
|
||||||
|
@ -882,7 +882,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
|
|
||||||
case Stmt::PseudoObjectExprClass: {
|
case Stmt::PseudoObjectExprClass: {
|
||||||
Bldr.takeNodes(Pred);
|
Bldr.takeNodes(Pred);
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
|
const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
|
||||||
if (const Expr *Result = PE->getResultExpr()) {
|
if (const Expr *Result = PE->getResultExpr()) {
|
||||||
SVal V = state->getSVal(Result, Pred->getLocationContext());
|
SVal V = state->getSVal(Result, Pred->getLocationContext());
|
||||||
|
@ -916,7 +916,7 @@ void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) {
|
||||||
// Branch processing.
|
// Branch processing.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
const ProgramState *ExprEngine::MarkBranch(const ProgramState *state,
|
ProgramStateRef ExprEngine::MarkBranch(ProgramStateRef state,
|
||||||
const Stmt *Terminator,
|
const Stmt *Terminator,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
bool branchTaken) {
|
bool branchTaken) {
|
||||||
|
@ -979,7 +979,7 @@ const ProgramState *ExprEngine::MarkBranch(const ProgramState *state,
|
||||||
/// This function returns the SVal bound to Condition->IgnoreCasts if all the
|
/// This function returns the SVal bound to Condition->IgnoreCasts if all the
|
||||||
// cast(s) did was sign-extend the original value.
|
// cast(s) did was sign-extend the original value.
|
||||||
static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
|
static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
const Stmt *Condition,
|
const Stmt *Condition,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
ASTContext &Ctx) {
|
ASTContext &Ctx) {
|
||||||
|
@ -1050,7 +1050,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
if (PredI->isSink())
|
if (PredI->isSink())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const ProgramState *PrevState = Pred->getState();
|
ProgramStateRef PrevState = Pred->getState();
|
||||||
SVal X = PrevState->getSVal(Condition, Pred->getLocationContext());
|
SVal X = PrevState->getSVal(Condition, Pred->getLocationContext());
|
||||||
|
|
||||||
if (X.isUnknownOrUndef()) {
|
if (X.isUnknownOrUndef()) {
|
||||||
|
@ -1088,7 +1088,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
|
|
||||||
// Process the true branch.
|
// Process the true branch.
|
||||||
if (builder.isFeasible(true)) {
|
if (builder.isFeasible(true)) {
|
||||||
if (const ProgramState *state = PrevState->assume(V, true))
|
if (ProgramStateRef state = PrevState->assume(V, true))
|
||||||
builder.generateNode(MarkBranch(state, Term, LCtx, true),
|
builder.generateNode(MarkBranch(state, Term, LCtx, true),
|
||||||
true, PredI);
|
true, PredI);
|
||||||
else
|
else
|
||||||
|
@ -1097,7 +1097,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
|
|
||||||
// Process the false branch.
|
// Process the false branch.
|
||||||
if (builder.isFeasible(false)) {
|
if (builder.isFeasible(false)) {
|
||||||
if (const ProgramState *state = PrevState->assume(V, false))
|
if (ProgramStateRef state = PrevState->assume(V, false))
|
||||||
builder.generateNode(MarkBranch(state, Term, LCtx, false),
|
builder.generateNode(MarkBranch(state, Term, LCtx, false),
|
||||||
false, PredI);
|
false, PredI);
|
||||||
else
|
else
|
||||||
|
@ -1111,7 +1111,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
/// nodes by processing the 'effects' of a computed goto jump.
|
/// nodes by processing the 'effects' of a computed goto jump.
|
||||||
void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
|
void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
|
||||||
|
|
||||||
const ProgramState *state = builder.getState();
|
ProgramStateRef state = builder.getState();
|
||||||
SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
|
SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
|
||||||
|
|
||||||
// Three possibilities:
|
// Three possibilities:
|
||||||
|
@ -1164,7 +1164,7 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC) {
|
||||||
/// nodes by processing the 'effects' of a switch statement.
|
/// nodes by processing the 'effects' of a switch statement.
|
||||||
void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
|
void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
|
||||||
typedef SwitchNodeBuilder::iterator iterator;
|
typedef SwitchNodeBuilder::iterator iterator;
|
||||||
const ProgramState *state = builder.getState();
|
ProgramStateRef state = builder.getState();
|
||||||
const Expr *CondE = builder.getCondition();
|
const Expr *CondE = builder.getCondition();
|
||||||
SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
|
SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
|
||||||
|
|
||||||
|
@ -1177,7 +1177,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
|
||||||
}
|
}
|
||||||
DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
|
DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
|
||||||
|
|
||||||
const ProgramState *DefaultSt = state;
|
ProgramStateRef DefaultSt = state;
|
||||||
|
|
||||||
iterator I = builder.begin(), EI = builder.end();
|
iterator I = builder.begin(), EI = builder.end();
|
||||||
bool defaultIsFeasible = I == EI;
|
bool defaultIsFeasible = I == EI;
|
||||||
|
@ -1210,7 +1210,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
|
||||||
CondV, CaseVal);
|
CondV, CaseVal);
|
||||||
|
|
||||||
// Now "assume" that the case matches.
|
// Now "assume" that the case matches.
|
||||||
if (const ProgramState *stateNew = state->assume(Res, true)) {
|
if (ProgramStateRef stateNew = state->assume(Res, true)) {
|
||||||
builder.generateCaseStmtNode(I, stateNew);
|
builder.generateCaseStmtNode(I, stateNew);
|
||||||
|
|
||||||
// If CondV evaluates to a constant, then we know that this
|
// If CondV evaluates to a constant, then we know that this
|
||||||
|
@ -1223,7 +1223,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
|
||||||
// Now "assume" that the case doesn't match. Add this state
|
// Now "assume" that the case doesn't match. Add this state
|
||||||
// to the default state (if it is feasible).
|
// to the default state (if it is feasible).
|
||||||
if (DefaultSt) {
|
if (DefaultSt) {
|
||||||
if (const ProgramState *stateNew = DefaultSt->assume(Res, false)) {
|
if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) {
|
||||||
defaultIsFeasible = true;
|
defaultIsFeasible = true;
|
||||||
DefaultSt = stateNew;
|
DefaultSt = stateNew;
|
||||||
}
|
}
|
||||||
|
@ -1272,7 +1272,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
|
|
||||||
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
||||||
|
@ -1325,7 +1325,7 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
|
||||||
for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
|
for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
|
||||||
ei = checkerPreStmt.end(); it != ei; ++it) {
|
ei = checkerPreStmt.end(); it != ei; ++it) {
|
||||||
const LocationContext *LCtx = (*it)->getLocationContext();
|
const LocationContext *LCtx = (*it)->getLocationContext();
|
||||||
const ProgramState *state = (*it)->getState();
|
ProgramStateRef state = (*it)->getState();
|
||||||
SVal V = state->getLValue(A->getType(),
|
SVal V = state->getLValue(A->getType(),
|
||||||
state->getSVal(Idx, LCtx),
|
state->getSVal(Idx, LCtx),
|
||||||
state->getSVal(Base, LCtx));
|
state->getSVal(Base, LCtx));
|
||||||
|
@ -1355,7 +1355,7 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Expr *baseExpr = M->getBase()->IgnoreParens();
|
Expr *baseExpr = M->getBase()->IgnoreParens();
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext());
|
SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext());
|
||||||
if (isa<nonloc::LazyCompoundVal>(baseExprVal) ||
|
if (isa<nonloc::LazyCompoundVal>(baseExprVal) ||
|
||||||
|
@ -1402,7 +1402,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
|
||||||
|
|
||||||
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
|
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
|
||||||
I!=E; ++I) {
|
I!=E; ++I) {
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
|
|
||||||
if (atDeclInit) {
|
if (atDeclInit) {
|
||||||
const VarRegion *VR =
|
const VarRegion *VR =
|
||||||
|
@ -1430,7 +1430,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
|
||||||
void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
|
void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
|
||||||
const Expr *LocationE,
|
const Expr *LocationE,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *state, SVal location, SVal Val,
|
ProgramStateRef state, SVal location, SVal Val,
|
||||||
const ProgramPointTag *tag) {
|
const ProgramPointTag *tag) {
|
||||||
// Proceed with the store. We use AssignE as the anchor for the PostStore
|
// Proceed with the store. We use AssignE as the anchor for the PostStore
|
||||||
// ProgramPoint if it is non-NULL, and LocationE otherwise.
|
// ProgramPoint if it is non-NULL, and LocationE otherwise.
|
||||||
|
@ -1459,7 +1459,7 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
|
||||||
|
|
||||||
void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
|
void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *state, SVal location,
|
ProgramStateRef state, SVal location,
|
||||||
const ProgramPointTag *tag, QualType LoadTy) {
|
const ProgramPointTag *tag, QualType LoadTy) {
|
||||||
assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
|
assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
|
||||||
|
|
||||||
|
@ -1498,7 +1498,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
|
||||||
|
|
||||||
void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex,
|
void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *state, SVal location,
|
ProgramStateRef state, SVal location,
|
||||||
const ProgramPointTag *tag, QualType LoadTy) {
|
const ProgramPointTag *tag, QualType LoadTy) {
|
||||||
|
|
||||||
// Evaluate the location (checks for bad dereferences).
|
// Evaluate the location (checks for bad dereferences).
|
||||||
|
@ -1534,7 +1534,7 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex,
|
||||||
|
|
||||||
void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *S,
|
void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *S,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *state, SVal location,
|
ProgramStateRef state, SVal location,
|
||||||
const ProgramPointTag *tag, bool isLoad) {
|
const ProgramPointTag *tag, bool isLoad) {
|
||||||
StmtNodeBuilder BldrTop(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder BldrTop(Pred, Dst, *currentBuilderContext);
|
||||||
// Early checks for performance reason.
|
// Early checks for performance reason.
|
||||||
|
@ -1588,7 +1588,7 @@ void ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal V = state->getSVal(Ex, Pred->getLocationContext());
|
SVal V = state->getSVal(Ex, Pred->getLocationContext());
|
||||||
nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
|
nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
|
||||||
if (SEV && SEV->isExpression()) {
|
if (SEV && SEV->isExpression()) {
|
||||||
|
@ -1596,14 +1596,14 @@ void ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||||
getEagerlyAssumeTags();
|
getEagerlyAssumeTags();
|
||||||
|
|
||||||
// First assume that the condition is true.
|
// First assume that the condition is true.
|
||||||
if (const ProgramState *StateTrue = state->assume(*SEV, true)) {
|
if (ProgramStateRef StateTrue = state->assume(*SEV, true)) {
|
||||||
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
|
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
|
||||||
StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
|
StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
|
||||||
Bldr.generateNode(Ex, Pred, StateTrue, false, tags.first);
|
Bldr.generateNode(Ex, Pred, StateTrue, false, tags.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, assume that the condition is false.
|
// Next, assume that the condition is false.
|
||||||
if (const ProgramState *StateFalse = state->assume(*SEV, false)) {
|
if (ProgramStateRef StateFalse = state->assume(*SEV, false)) {
|
||||||
SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
|
SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
|
||||||
StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
|
StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
|
||||||
Bldr.generateNode(Ex, Pred, StateFalse, false, tags.second);
|
Bldr.generateNode(Ex, Pred, StateFalse, false, tags.second);
|
||||||
|
@ -1648,7 +1648,7 @@ void ExprEngine::VisitAsmStmtHelperInputs(const AsmStmt *A,
|
||||||
// which interprets the inline asm and stores proper results in the
|
// which interprets the inline asm and stores proper results in the
|
||||||
// outputs.
|
// outputs.
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
|
|
||||||
for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
|
for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
|
||||||
OE = A->end_outputs(); OI != OE; ++OI) {
|
OE = A->end_outputs(); OI != OE; ++OI) {
|
||||||
|
@ -1855,7 +1855,7 @@ struct DOTGraphTraits<ExplodedNode*> :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
Out << "\\|StateID: " << (void*) state
|
Out << "\\|StateID: " << (void*) state
|
||||||
<< " NodeID: " << (void*) N << "\\|";
|
<< " NodeID: " << (void*) N << "\\|";
|
||||||
state->printDOT(Out);
|
state->printDOT(Out);
|
||||||
|
|
|
@ -34,7 +34,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
||||||
for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
|
for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
|
||||||
it != ei; ++it) {
|
it != ei; ++it) {
|
||||||
|
|
||||||
const ProgramState *state = (*it)->getState();
|
ProgramStateRef state = (*it)->getState();
|
||||||
const LocationContext *LCtx = (*it)->getLocationContext();
|
const LocationContext *LCtx = (*it)->getLocationContext();
|
||||||
SVal LeftV = state->getSVal(LHS, LCtx);
|
SVal LeftV = state->getSVal(LHS, LCtx);
|
||||||
SVal RightV = state->getSVal(RHS, LCtx);
|
SVal RightV = state->getSVal(RHS, LCtx);
|
||||||
|
@ -187,7 +187,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||||
for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
|
for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
|
||||||
I!=E; ++I) {
|
I!=E; ++I) {
|
||||||
ExplodedNode *subExprNode = *I;
|
ExplodedNode *subExprNode = *I;
|
||||||
const ProgramState *state = subExprNode->getState();
|
ProgramStateRef state = subExprNode->getState();
|
||||||
const LocationContext *LCtx = subExprNode->getLocationContext();
|
const LocationContext *LCtx = subExprNode->getLocationContext();
|
||||||
evalLoad(Dst, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
|
evalLoad(Dst, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||||
case CK_NoOp:
|
case CK_NoOp:
|
||||||
case CK_FunctionToPointerDecay: {
|
case CK_FunctionToPointerDecay: {
|
||||||
// Copy the SVal of Ex to CastE.
|
// Copy the SVal of Ex to CastE.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal V = state->getSVal(Ex, LCtx);
|
SVal V = state->getSVal(Ex, LCtx);
|
||||||
state = state->BindExpr(CastE, LCtx, V);
|
state = state->BindExpr(CastE, LCtx, V);
|
||||||
|
@ -263,7 +263,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||||
case CK_AnyPointerToBlockPointerCast:
|
case CK_AnyPointerToBlockPointerCast:
|
||||||
case CK_ObjCObjectLValueCast: {
|
case CK_ObjCObjectLValueCast: {
|
||||||
// Delegate to SValBuilder to process.
|
// Delegate to SValBuilder to process.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal V = state->getSVal(Ex, LCtx);
|
SVal V = state->getSVal(Ex, LCtx);
|
||||||
V = svalBuilder.evalCast(V, T, ExTy);
|
V = svalBuilder.evalCast(V, T, ExTy);
|
||||||
|
@ -274,7 +274,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||||
case CK_DerivedToBase:
|
case CK_DerivedToBase:
|
||||||
case CK_UncheckedDerivedToBase: {
|
case CK_UncheckedDerivedToBase: {
|
||||||
// For DerivedToBase cast, delegate to the store manager.
|
// For DerivedToBase cast, delegate to the store manager.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal val = state->getSVal(Ex, LCtx);
|
SVal val = state->getSVal(Ex, LCtx);
|
||||||
val = getStoreManager().evalDerivedToBase(val, T);
|
val = getStoreManager().evalDerivedToBase(val, T);
|
||||||
|
@ -303,7 +303,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||||
currentBuilderContext->getCurrentBlockCount());
|
currentBuilderContext->getCurrentBlockCount());
|
||||||
|
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
const ProgramState *state = Pred->getState()->BindExpr(CastE, LCtx,
|
ProgramStateRef state = Pred->getState()->BindExpr(CastE, LCtx,
|
||||||
result);
|
result);
|
||||||
Bldr.generateNode(CastE, Pred, state);
|
Bldr.generateNode(CastE, Pred, state);
|
||||||
continue;
|
continue;
|
||||||
|
@ -320,7 +320,7 @@ void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
|
||||||
const InitListExpr *ILE
|
const InitListExpr *ILE
|
||||||
= cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
|
= cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
|
SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
|
||||||
const LocationContext *LC = Pred->getLocationContext();
|
const LocationContext *LC = Pred->getLocationContext();
|
||||||
state = state->bindCompoundLiteral(CL, LC, ILV);
|
state = state->bindCompoundLiteral(CL, LC, ILV);
|
||||||
|
@ -356,7 +356,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
|
||||||
for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
|
for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
|
||||||
I!=E; ++I) {
|
I!=E; ++I) {
|
||||||
ExplodedNode *N = *I;
|
ExplodedNode *N = *I;
|
||||||
const ProgramState *state = N->getState();
|
ProgramStateRef state = N->getState();
|
||||||
|
|
||||||
// Decls without InitExpr are not initialized explicitly.
|
// Decls without InitExpr are not initialized explicitly.
|
||||||
const LocationContext *LC = N->getLocationContext();
|
const LocationContext *LC = N->getLocationContext();
|
||||||
|
@ -395,7 +395,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
B->getOpcode() == BO_LOr);
|
B->getOpcode() == BO_LOr);
|
||||||
|
|
||||||
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal X = state->getSVal(B, LCtx);
|
SVal X = state->getSVal(B, LCtx);
|
||||||
assert(X.isUndef());
|
assert(X.isUndef());
|
||||||
|
@ -420,12 +420,12 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
// value later when necessary. We don't have the machinery in place for
|
// value later when necessary. We don't have the machinery in place for
|
||||||
// this right now, and since most logical expressions are used for branches,
|
// this right now, and since most logical expressions are used for branches,
|
||||||
// the payoff is not likely to be large. Instead, we do eager evaluation.
|
// the payoff is not likely to be large. Instead, we do eager evaluation.
|
||||||
if (const ProgramState *newState = state->assume(XD, true))
|
if (ProgramStateRef newState = state->assume(XD, true))
|
||||||
Bldr.generateNode(B, Pred,
|
Bldr.generateNode(B, Pred,
|
||||||
newState->BindExpr(B, LCtx,
|
newState->BindExpr(B, LCtx,
|
||||||
svalBuilder.makeIntVal(1U, B->getType())));
|
svalBuilder.makeIntVal(1U, B->getType())));
|
||||||
|
|
||||||
if (const ProgramState *newState = state->assume(XD, false))
|
if (ProgramStateRef newState = state->assume(XD, false))
|
||||||
Bldr.generateNode(B, Pred,
|
Bldr.generateNode(B, Pred,
|
||||||
newState->BindExpr(B, LCtx,
|
newState->BindExpr(B, LCtx,
|
||||||
svalBuilder.makeIntVal(0U, B->getType())));
|
svalBuilder.makeIntVal(0U, B->getType())));
|
||||||
|
@ -445,7 +445,7 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
QualType T = getContext().getCanonicalType(IE->getType());
|
QualType T = getContext().getCanonicalType(IE->getType());
|
||||||
unsigned NumInitElements = IE->getNumInits();
|
unsigned NumInitElements = IE->getNumInits();
|
||||||
|
@ -491,7 +491,7 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal X = state->getSVal(Ex, LCtx);
|
SVal X = state->getSVal(Ex, LCtx);
|
||||||
assert (X.isUndef());
|
assert (X.isUndef());
|
||||||
|
@ -548,7 +548,7 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
|
||||||
APSInt Value = Ex->EvaluateKnownConstInt(getContext());
|
APSInt Value = Ex->EvaluateKnownConstInt(getContext());
|
||||||
CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
|
CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
state = state->BindExpr(Ex, Pred->getLocationContext(),
|
state = state->BindExpr(Ex, Pred->getLocationContext(),
|
||||||
svalBuilder.makeIntVal(amt.getQuantity(),
|
svalBuilder.makeIntVal(amt.getQuantity(),
|
||||||
Ex->getType()));
|
Ex->getType()));
|
||||||
|
@ -582,7 +582,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
||||||
|
|
||||||
// For all other types, UO_Real is an identity operation.
|
// For all other types, UO_Real is an identity operation.
|
||||||
assert (U->getType() == Ex->getType());
|
assert (U->getType() == Ex->getType());
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
const LocationContext *LCtx = (*I)->getLocationContext();
|
const LocationContext *LCtx = (*I)->getLocationContext();
|
||||||
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
|
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
|
||||||
state->getSVal(Ex, LCtx)));
|
state->getSVal(Ex, LCtx)));
|
||||||
|
@ -605,7 +605,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all other types, UO_Imag returns 0.
|
// For all other types, UO_Imag returns 0.
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
const LocationContext *LCtx = (*I)->getLocationContext();
|
const LocationContext *LCtx = (*I)->getLocationContext();
|
||||||
SVal X = svalBuilder.makeZeroVal(Ex->getType());
|
SVal X = svalBuilder.makeZeroVal(Ex->getType());
|
||||||
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
|
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
|
||||||
|
@ -631,7 +631,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
||||||
Visit(Ex, Pred, Tmp);
|
Visit(Ex, Pred, Tmp);
|
||||||
|
|
||||||
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
const LocationContext *LCtx = (*I)->getLocationContext();
|
const LocationContext *LCtx = (*I)->getLocationContext();
|
||||||
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
|
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
|
||||||
state->getSVal(Ex, LCtx)));
|
state->getSVal(Ex, LCtx)));
|
||||||
|
@ -649,7 +649,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
||||||
Visit(Ex, Pred, Tmp);
|
Visit(Ex, Pred, Tmp);
|
||||||
|
|
||||||
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
const LocationContext *LCtx = (*I)->getLocationContext();
|
const LocationContext *LCtx = (*I)->getLocationContext();
|
||||||
|
|
||||||
// Get the value of the subexpression.
|
// Get the value of the subexpression.
|
||||||
|
@ -716,7 +716,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
|
||||||
|
|
||||||
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
|
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
|
||||||
const LocationContext *LCtx = (*I)->getLocationContext();
|
const LocationContext *LCtx = (*I)->getLocationContext();
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
SVal loc = state->getSVal(Ex, LCtx);
|
SVal loc = state->getSVal(Ex, LCtx);
|
||||||
|
|
||||||
// Perform a load.
|
// Perform a load.
|
||||||
|
|
|
@ -109,7 +109,7 @@ void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
||||||
const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
|
const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
|
|
||||||
// Bind the temporary object to the value of the expression. Then bind
|
// Bind the temporary object to the value of the expression. Then bind
|
||||||
|
@ -187,7 +187,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
|
||||||
StmtNodeBuilder Bldr(argsEvaluated, destNodes, *currentBuilderContext);
|
StmtNodeBuilder Bldr(argsEvaluated, destNodes, *currentBuilderContext);
|
||||||
for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
|
for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
|
||||||
NE = argsEvaluated.end(); NI != NE; ++NI) {
|
NE = argsEvaluated.end(); NI != NE; ++NI) {
|
||||||
const ProgramState *state = (*NI)->getState();
|
ProgramStateRef state = (*NI)->getState();
|
||||||
// Setup 'this' region, so that the ctor is evaluated on the object pointed
|
// Setup 'this' region, so that the ctor is evaluated on the object pointed
|
||||||
// by 'Dest'.
|
// by 'Dest'.
|
||||||
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
||||||
|
@ -206,7 +206,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
|
||||||
{
|
{
|
||||||
ExplodedNode *Pred = *i;
|
ExplodedNode *Pred = *i;
|
||||||
const LocationContext *LC = Pred->getLocationContext();
|
const LocationContext *LC = Pred->getLocationContext();
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
|
|
||||||
state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC);
|
state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC);
|
||||||
Bldr.generateNode(E, Pred, state);
|
Bldr.generateNode(E, Pred, state);
|
||||||
|
@ -235,7 +235,7 @@ void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
|
||||||
|
|
||||||
CallEnter PP(S, SFC, Pred->getLocationContext());
|
CallEnter PP(S, SFC, Pred->getLocationContext());
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
|
||||||
Bldr.generateNode(PP, Pred, state);
|
Bldr.generateNode(PP, Pred, state);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||||
if (CNE->isArray()) {
|
if (CNE->isArray()) {
|
||||||
// FIXME: allocating an array requires simulating the constructors.
|
// FIXME: allocating an array requires simulating the constructors.
|
||||||
// For now, just return a symbolicated region.
|
// For now, just return a symbolicated region.
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
state = state->BindExpr(CNE, Pred->getLocationContext(),
|
state = state->BindExpr(CNE, Pred->getLocationContext(),
|
||||||
loc::MemRegionVal(EleReg));
|
loc::MemRegionVal(EleReg));
|
||||||
Bldr.generateNode(CNE, Pred, state);
|
Bldr.generateNode(CNE, Pred, state);
|
||||||
|
@ -277,7 +277,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||||
for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
|
for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
|
||||||
E = argsEvaluated.end(); I != E; ++I) {
|
E = argsEvaluated.end(); I != E; ++I) {
|
||||||
|
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
|
|
||||||
// Accumulate list of regions that are invalidated.
|
// Accumulate list of regions that are invalidated.
|
||||||
// FIXME: Eventually we should unify the logic for constructor
|
// FIXME: Eventually we should unify the logic for constructor
|
||||||
|
@ -331,7 +331,7 @@ void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
|
||||||
StmtNodeBuilder Bldr(Argevaluated, Dst, *currentBuilderContext);
|
StmtNodeBuilder Bldr(Argevaluated, Dst, *currentBuilderContext);
|
||||||
for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
|
for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
|
||||||
E = Argevaluated.end(); I != E; ++I) {
|
E = Argevaluated.end(); I != E; ++I) {
|
||||||
const ProgramState *state = (*I)->getState();
|
ProgramStateRef state = (*I)->getState();
|
||||||
Bldr.generateNode(CDE, *I, state);
|
Bldr.generateNode(CDE, *I, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
|
||||||
getContext().getCanonicalType(TE->getType()),
|
getContext().getCanonicalType(TE->getType()),
|
||||||
LCtx);
|
LCtx);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal V = state->getSVal(loc::MemRegionVal(R));
|
SVal V = state->getSVal(loc::MemRegionVal(R));
|
||||||
Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
|
Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ void ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) {
|
||||||
// Construct a new state which contains the mapping from actual to
|
// Construct a new state which contains the mapping from actual to
|
||||||
// formal arguments.
|
// formal arguments.
|
||||||
const LocationContext *callerCtx = Pred->getLocationContext();
|
const LocationContext *callerCtx = Pred->getLocationContext();
|
||||||
const ProgramState *state = Pred->getState()->enterStackFrame(callerCtx,
|
ProgramStateRef state = Pred->getState()->enterStackFrame(callerCtx,
|
||||||
calleeCtx);
|
calleeCtx);
|
||||||
|
|
||||||
// Construct a new node and add it to the worklist.
|
// Construct a new node and add it to the worklist.
|
||||||
|
@ -69,7 +69,7 @@ static const ReturnStmt *getReturnStmt(const ExplodedNode *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprEngine::processCallExit(ExplodedNode *Pred) {
|
void ExprEngine::processCallExit(ExplodedNode *Pred) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const StackFrameContext *calleeCtx =
|
const StackFrameContext *calleeCtx =
|
||||||
Pred->getLocationContext()->getCurrentStackFrame();
|
Pred->getLocationContext()->getCurrentStackFrame();
|
||||||
const LocationContext *callerCtx = calleeCtx->getParent();
|
const LocationContext *callerCtx = calleeCtx->getParent();
|
||||||
|
@ -130,7 +130,7 @@ static unsigned getNumberStackFrames(const LocationContext *LCtx) {
|
||||||
bool ExprEngine::InlineCall(ExplodedNodeSet &Dst,
|
bool ExprEngine::InlineCall(ExplodedNodeSet &Dst,
|
||||||
const CallExpr *CE,
|
const CallExpr *CE,
|
||||||
ExplodedNode *Pred) {
|
ExplodedNode *Pred) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const Expr *Callee = CE->getCallee();
|
const Expr *Callee = CE->getCallee();
|
||||||
const FunctionDecl *FD =
|
const FunctionDecl *FD =
|
||||||
state->getSVal(Callee, Pred->getLocationContext()).getAsFunctionDecl();
|
state->getSVal(Callee, Pred->getLocationContext()).getAsFunctionDecl();
|
||||||
|
@ -208,8 +208,8 @@ static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ExprEngine::invalidateArguments(const ProgramState *State,
|
ExprEngine::invalidateArguments(ProgramStateRef State,
|
||||||
const CallOrObjCMessage &Call,
|
const CallOrObjCMessage &Call,
|
||||||
const LocationContext *LC) {
|
const LocationContext *LC) {
|
||||||
SmallVector<const MemRegion *, 8> RegionsToInvalidate;
|
SmallVector<const MemRegion *, 8> RegionsToInvalidate;
|
||||||
|
@ -335,7 +335,7 @@ void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
|
||||||
|
|
||||||
// Get the callee.
|
// Get the callee.
|
||||||
const Expr *Callee = CE->getCallee()->IgnoreParens();
|
const Expr *Callee = CE->getCallee()->IgnoreParens();
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal L = state->getSVal(Callee, Pred->getLocationContext());
|
SVal L = state->getSVal(Callee, Pred->getLocationContext());
|
||||||
|
|
||||||
// Figure out the result type. We do this dance to handle references.
|
// Figure out the result type. We do this dance to handle references.
|
||||||
|
|
|
@ -21,7 +21,7 @@ using namespace ento;
|
||||||
void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
|
void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
SVal baseVal = state->getSVal(Ex->getBase(), LCtx);
|
SVal baseVal = state->getSVal(Ex->getBase(), LCtx);
|
||||||
SVal location = state->getLValue(Ex->getDecl(), baseVal);
|
SVal location = state->getLValue(Ex->getDecl(), baseVal);
|
||||||
|
@ -71,7 +71,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
|
||||||
// result in state splitting.
|
// result in state splitting.
|
||||||
|
|
||||||
const Stmt *elem = S->getElement();
|
const Stmt *elem = S->getElement();
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal elementV;
|
SVal elementV;
|
||||||
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
|
@ -92,16 +92,16 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
|
||||||
for (ExplodedNodeSet::iterator NI = dstLocation.begin(),
|
for (ExplodedNodeSet::iterator NI = dstLocation.begin(),
|
||||||
NE = dstLocation.end(); NI!=NE; ++NI) {
|
NE = dstLocation.end(); NI!=NE; ++NI) {
|
||||||
Pred = *NI;
|
Pred = *NI;
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
const LocationContext *LCtx = Pred->getLocationContext();
|
const LocationContext *LCtx = Pred->getLocationContext();
|
||||||
|
|
||||||
// Handle the case where the container still has elements.
|
// Handle the case where the container still has elements.
|
||||||
SVal TrueV = svalBuilder.makeTruthVal(1);
|
SVal TrueV = svalBuilder.makeTruthVal(1);
|
||||||
const ProgramState *hasElems = state->BindExpr(S, LCtx, TrueV);
|
ProgramStateRef hasElems = state->BindExpr(S, LCtx, TrueV);
|
||||||
|
|
||||||
// Handle the case where the container has no elements.
|
// Handle the case where the container has no elements.
|
||||||
SVal FalseV = svalBuilder.makeTruthVal(0);
|
SVal FalseV = svalBuilder.makeTruthVal(0);
|
||||||
const ProgramState *noElems = state->BindExpr(S, LCtx, FalseV);
|
ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
|
||||||
|
|
||||||
if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
|
if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
|
||||||
if (const TypedValueRegion *R =
|
if (const TypedValueRegion *R =
|
||||||
|
@ -147,13 +147,13 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
|
||||||
bool RaisesException = false;
|
bool RaisesException = false;
|
||||||
|
|
||||||
if (const Expr *Receiver = msg.getInstanceReceiver()) {
|
if (const Expr *Receiver = msg.getInstanceReceiver()) {
|
||||||
const ProgramState *state = Pred->getState();
|
ProgramStateRef state = Pred->getState();
|
||||||
SVal recVal = state->getSVal(Receiver, Pred->getLocationContext());
|
SVal recVal = state->getSVal(Receiver, Pred->getLocationContext());
|
||||||
if (!recVal.isUndef()) {
|
if (!recVal.isUndef()) {
|
||||||
// Bifurcate the state into nil and non-nil ones.
|
// Bifurcate the state into nil and non-nil ones.
|
||||||
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
|
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
|
||||||
|
|
||||||
const ProgramState *notNilState, *nilState;
|
ProgramStateRef notNilState, nilState;
|
||||||
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
|
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
|
||||||
|
|
||||||
// There are three cases: can be nil or non-nil, must be nil, must be
|
// There are three cases: can be nil or non-nil, must be nil, must be
|
||||||
|
@ -228,7 +228,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
|
||||||
void ExprEngine::evalObjCMessage(StmtNodeBuilder &Bldr,
|
void ExprEngine::evalObjCMessage(StmtNodeBuilder &Bldr,
|
||||||
const ObjCMessage &msg,
|
const ObjCMessage &msg,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *state,
|
ProgramStateRef state,
|
||||||
bool GenSink) {
|
bool GenSink) {
|
||||||
// First handle the return value.
|
// First handle the return value.
|
||||||
SVal ReturnValue = UnknownVal();
|
SVal ReturnValue = UnknownVal();
|
||||||
|
|
|
@ -56,8 +56,8 @@ ProgramStateManager::~ProgramStateManager() {
|
||||||
I->second.second(I->second.first);
|
I->second.second(I->second.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
ProgramStateManager::removeDeadBindings(const ProgramState *state,
|
ProgramStateManager::removeDeadBindings(ProgramStateRef state,
|
||||||
const StackFrameContext *LCtx,
|
const StackFrameContext *LCtx,
|
||||||
SymbolReaper& SymReaper) {
|
SymbolReaper& SymReaper) {
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ ProgramStateManager::removeDeadBindings(const ProgramState *state,
|
||||||
return getPersistentState(NewState);
|
return getPersistentState(NewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::MarshalState(const ProgramState *state,
|
ProgramStateRef ProgramStateManager::MarshalState(ProgramStateRef state,
|
||||||
const StackFrameContext *InitLoc) {
|
const StackFrameContext *InitLoc) {
|
||||||
// make up an empty state for now.
|
// make up an empty state for now.
|
||||||
ProgramState State(this,
|
ProgramState State(this,
|
||||||
|
@ -91,7 +91,7 @@ const ProgramState *ProgramStateManager::MarshalState(const ProgramState *state,
|
||||||
return getPersistentState(State);
|
return getPersistentState(State);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::bindCompoundLiteral(const CompoundLiteralExpr *CL,
|
ProgramStateRef ProgramState::bindCompoundLiteral(const CompoundLiteralExpr *CL,
|
||||||
const LocationContext *LC,
|
const LocationContext *LC,
|
||||||
SVal V) const {
|
SVal V) const {
|
||||||
const StoreRef &newStore =
|
const StoreRef &newStore =
|
||||||
|
@ -99,21 +99,21 @@ const ProgramState *ProgramState::bindCompoundLiteral(const CompoundLiteralExpr
|
||||||
return makeWithStore(newStore);
|
return makeWithStore(newStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::bindDecl(const VarRegion* VR, SVal IVal) const {
|
ProgramStateRef ProgramState::bindDecl(const VarRegion* VR, SVal IVal) const {
|
||||||
const StoreRef &newStore =
|
const StoreRef &newStore =
|
||||||
getStateManager().StoreMgr->BindDecl(getStore(), VR, IVal);
|
getStateManager().StoreMgr->BindDecl(getStore(), VR, IVal);
|
||||||
return makeWithStore(newStore);
|
return makeWithStore(newStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::bindDeclWithNoInit(const VarRegion* VR) const {
|
ProgramStateRef ProgramState::bindDeclWithNoInit(const VarRegion* VR) const {
|
||||||
const StoreRef &newStore =
|
const StoreRef &newStore =
|
||||||
getStateManager().StoreMgr->BindDeclWithNoInit(getStore(), VR);
|
getStateManager().StoreMgr->BindDeclWithNoInit(getStore(), VR);
|
||||||
return makeWithStore(newStore);
|
return makeWithStore(newStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::bindLoc(Loc LV, SVal V) const {
|
ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V) const {
|
||||||
ProgramStateManager &Mgr = getStateManager();
|
ProgramStateManager &Mgr = getStateManager();
|
||||||
const ProgramState *newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
|
ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
|
||||||
LV, V));
|
LV, V));
|
||||||
const MemRegion *MR = LV.getAsRegion();
|
const MemRegion *MR = LV.getAsRegion();
|
||||||
if (MR && Mgr.getOwningEngine())
|
if (MR && Mgr.getOwningEngine())
|
||||||
|
@ -122,17 +122,17 @@ const ProgramState *ProgramState::bindLoc(Loc LV, SVal V) const {
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::bindDefault(SVal loc, SVal V) const {
|
ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
|
||||||
ProgramStateManager &Mgr = getStateManager();
|
ProgramStateManager &Mgr = getStateManager();
|
||||||
const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
|
const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
|
||||||
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
|
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
|
||||||
const ProgramState *new_state = makeWithStore(newStore);
|
ProgramStateRef new_state = makeWithStore(newStore);
|
||||||
return Mgr.getOwningEngine() ?
|
return Mgr.getOwningEngine() ?
|
||||||
Mgr.getOwningEngine()->processRegionChange(new_state, R) :
|
Mgr.getOwningEngine()->processRegionChange(new_state, R) :
|
||||||
new_state;
|
new_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
|
ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
|
||||||
const Expr *E, unsigned Count,
|
const Expr *E, unsigned Count,
|
||||||
StoreManager::InvalidatedSymbols *IS,
|
StoreManager::InvalidatedSymbols *IS,
|
||||||
|
@ -145,7 +145,7 @@ ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
|
||||||
return invalidateRegionsImpl(Regions, E, Count, *IS, Call);
|
return invalidateRegionsImpl(Regions, E, Count, *IS, Call);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
||||||
const Expr *E, unsigned Count,
|
const Expr *E, unsigned Count,
|
||||||
StoreManager::InvalidatedSymbols &IS,
|
StoreManager::InvalidatedSymbols &IS,
|
||||||
|
@ -158,7 +158,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
||||||
const StoreRef &newStore
|
const StoreRef &newStore
|
||||||
= Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
|
= Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
|
||||||
Call, &Invalidated);
|
Call, &Invalidated);
|
||||||
const ProgramState *newState = makeWithStore(newStore);
|
ProgramStateRef newState = makeWithStore(newStore);
|
||||||
return Eng->processRegionChanges(newState, &IS, Regions, Invalidated);
|
return Eng->processRegionChanges(newState, &IS, Regions, Invalidated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
|
||||||
return makeWithStore(newStore);
|
return makeWithStore(newStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::unbindLoc(Loc LV) const {
|
ProgramStateRef ProgramState::unbindLoc(Loc LV) const {
|
||||||
assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
|
assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
|
||||||
|
|
||||||
Store OldStore = getStore();
|
Store OldStore = getStore();
|
||||||
|
@ -180,7 +180,7 @@ const ProgramState *ProgramState::unbindLoc(Loc LV) const {
|
||||||
return makeWithStore(newStore);
|
return makeWithStore(newStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ProgramState::enterStackFrame(const LocationContext *callerCtx,
|
ProgramState::enterStackFrame(const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx) const {
|
const StackFrameContext *calleeCtx) const {
|
||||||
const StoreRef &new_store =
|
const StoreRef &new_store =
|
||||||
|
@ -241,7 +241,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::BindExpr(const Stmt *S,
|
ProgramStateRef ProgramState::BindExpr(const Stmt *S,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
SVal V, bool Invalidate) const{
|
SVal V, bool Invalidate) const{
|
||||||
Environment NewEnv =
|
Environment NewEnv =
|
||||||
|
@ -255,7 +255,7 @@ const ProgramState *ProgramState::BindExpr(const Stmt *S,
|
||||||
return getStateManager().getPersistentState(NewSt);
|
return getStateManager().getPersistentState(NewSt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *
|
ProgramStateRef
|
||||||
ProgramState::bindExprAndLocation(const Stmt *S, const LocationContext *LCtx,
|
ProgramState::bindExprAndLocation(const Stmt *S, const LocationContext *LCtx,
|
||||||
SVal location,
|
SVal location,
|
||||||
SVal V) const {
|
SVal V) const {
|
||||||
|
@ -272,7 +272,7 @@ ProgramState::bindExprAndLocation(const Stmt *S, const LocationContext *LCtx,
|
||||||
return getStateManager().getPersistentState(NewSt);
|
return getStateManager().getPersistentState(NewSt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||||
DefinedOrUnknownSVal UpperBound,
|
DefinedOrUnknownSVal UpperBound,
|
||||||
bool Assumption) const {
|
bool Assumption) const {
|
||||||
if (Idx.isUnknown() || UpperBound.isUnknown())
|
if (Idx.isUnknown() || UpperBound.isUnknown())
|
||||||
|
@ -317,7 +317,7 @@ const ProgramState *ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||||
return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
|
return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
|
ProgramStateRef ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
|
||||||
ProgramState State(this,
|
ProgramState State(this,
|
||||||
EnvMgr.getInitialEnvironment(),
|
EnvMgr.getInitialEnvironment(),
|
||||||
StoreMgr->getInitialStore(InitLoc),
|
StoreMgr->getInitialStore(InitLoc),
|
||||||
|
@ -339,15 +339,15 @@ void ProgramStateManager::recycleUnusedStates() {
|
||||||
recentlyAllocatedStates.clear();
|
recentlyAllocatedStates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::getPersistentStateWithGDM(
|
ProgramStateRef ProgramStateManager::getPersistentStateWithGDM(
|
||||||
const ProgramState *FromState,
|
ProgramStateRef FromState,
|
||||||
const ProgramState *GDMState) {
|
ProgramStateRef GDMState) {
|
||||||
ProgramState NewState = *FromState;
|
ProgramState NewState = *FromState;
|
||||||
NewState.GDM = GDMState->GDM;
|
NewState.GDM = GDMState->GDM;
|
||||||
return getPersistentState(NewState);
|
return getPersistentState(NewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::getPersistentState(ProgramState &State) {
|
ProgramStateRef ProgramStateManager::getPersistentState(ProgramState &State) {
|
||||||
|
|
||||||
llvm::FoldingSetNodeID ID;
|
llvm::FoldingSetNodeID ID;
|
||||||
State.Profile(ID);
|
State.Profile(ID);
|
||||||
|
@ -370,7 +370,7 @@ const ProgramState *ProgramStateManager::getPersistentState(ProgramState &State)
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramState::makeWithStore(const StoreRef &store) const {
|
ProgramStateRef ProgramState::makeWithStore(const StoreRef &store) const {
|
||||||
ProgramState NewSt = *this;
|
ProgramState NewSt = *this;
|
||||||
NewSt.setStore(store);
|
NewSt.setStore(store);
|
||||||
return getStateManager().getPersistentState(NewSt);
|
return getStateManager().getPersistentState(NewSt);
|
||||||
|
@ -451,7 +451,7 @@ ProgramStateManager::FindGDMContext(void *K,
|
||||||
return p.first;
|
return p.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::addGDM(const ProgramState *St, void *Key, void *Data){
|
ProgramStateRef ProgramStateManager::addGDM(ProgramStateRef St, void *Key, void *Data){
|
||||||
ProgramState::GenericDataMap M1 = St->getGDM();
|
ProgramState::GenericDataMap M1 = St->getGDM();
|
||||||
ProgramState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
|
ProgramState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ const ProgramState *ProgramStateManager::addGDM(const ProgramState *St, void *Ke
|
||||||
return getPersistentState(NewSt);
|
return getPersistentState(NewSt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *ProgramStateManager::removeGDM(const ProgramState *state, void *Key) {
|
ProgramStateRef ProgramStateManager::removeGDM(ProgramStateRef state, void *Key) {
|
||||||
ProgramState::GenericDataMap OldM = state->getGDM();
|
ProgramState::GenericDataMap OldM = state->getGDM();
|
||||||
ProgramState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
|
ProgramState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
|
||||||
|
|
||||||
|
@ -592,7 +592,7 @@ bool ProgramState::scanReachableSymbols(const MemRegion * const *I,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState* ProgramState::addTaint(const Stmt *S,
|
ProgramStateRef ProgramState::addTaint(const Stmt *S,
|
||||||
const LocationContext *LCtx,
|
const LocationContext *LCtx,
|
||||||
TaintTagType Kind) const {
|
TaintTagType Kind) const {
|
||||||
if (const Expr *E = dyn_cast_or_null<Expr>(S))
|
if (const Expr *E = dyn_cast_or_null<Expr>(S))
|
||||||
|
@ -609,21 +609,21 @@ const ProgramState* ProgramState::addTaint(const Stmt *S,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState* ProgramState::addTaint(const MemRegion *R,
|
ProgramStateRef ProgramState::addTaint(const MemRegion *R,
|
||||||
TaintTagType Kind) const {
|
TaintTagType Kind) const {
|
||||||
if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
|
if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
|
||||||
return addTaint(SR->getSymbol(), Kind);
|
return addTaint(SR->getSymbol(), Kind);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState* ProgramState::addTaint(SymbolRef Sym,
|
ProgramStateRef ProgramState::addTaint(SymbolRef Sym,
|
||||||
TaintTagType Kind) const {
|
TaintTagType Kind) const {
|
||||||
// If this is a symbol cast, remove the cast before adding the taint. Taint
|
// If this is a symbol cast, remove the cast before adding the taint. Taint
|
||||||
// is cast agnostic.
|
// is cast agnostic.
|
||||||
while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
|
while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
|
||||||
Sym = SC->getOperand();
|
Sym = SC->getOperand();
|
||||||
|
|
||||||
const ProgramState *NewState = set<TaintMap>(Sym, Kind);
|
ProgramStateRef NewState = set<TaintMap>(Sym, Kind);
|
||||||
assert(NewState);
|
assert(NewState);
|
||||||
return NewState;
|
return NewState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,46 +204,46 @@ struct ProgramStateTrait<ConstraintRange>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class RangeConstraintManager : public SimpleConstraintManager{
|
class RangeConstraintManager : public SimpleConstraintManager{
|
||||||
RangeSet GetRange(const ProgramState *state, SymbolRef sym);
|
RangeSet GetRange(ProgramStateRef state, SymbolRef sym);
|
||||||
public:
|
public:
|
||||||
RangeConstraintManager(SubEngine &subengine)
|
RangeConstraintManager(SubEngine &subengine)
|
||||||
: SimpleConstraintManager(subengine) {}
|
: SimpleConstraintManager(subengine) {}
|
||||||
|
|
||||||
const ProgramState *assumeSymNE(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymNE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymEQ(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymEQ(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymLT(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymLT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymGT(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymGT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymGE(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymGE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const ProgramState *assumeSymLE(const ProgramState *state, SymbolRef sym,
|
ProgramStateRef assumeSymLE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment);
|
const llvm::APSInt& Adjustment);
|
||||||
|
|
||||||
const llvm::APSInt* getSymVal(const ProgramState *St, SymbolRef sym) const;
|
const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) const;
|
||||||
|
|
||||||
// FIXME: Refactor into SimpleConstraintManager?
|
// FIXME: Refactor into SimpleConstraintManager?
|
||||||
bool isEqual(const ProgramState *St, SymbolRef sym, const llvm::APSInt& V) const {
|
bool isEqual(ProgramStateRef St, SymbolRef sym, const llvm::APSInt& V) const {
|
||||||
const llvm::APSInt *i = getSymVal(St, sym);
|
const llvm::APSInt *i = getSymVal(St, sym);
|
||||||
return i ? *i == V : false;
|
return i ? *i == V : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *removeDeadBindings(const ProgramState *St, SymbolReaper& SymReaper);
|
ProgramStateRef removeDeadBindings(ProgramStateRef St, SymbolReaper& SymReaper);
|
||||||
|
|
||||||
void print(const ProgramState *St, raw_ostream &Out,
|
void print(ProgramStateRef St, raw_ostream &Out,
|
||||||
const char* nl, const char *sep);
|
const char* nl, const char *sep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -257,7 +257,7 @@ ConstraintManager* ento::CreateRangeConstraintManager(ProgramStateManager&,
|
||||||
return new RangeConstraintManager(subeng);
|
return new RangeConstraintManager(subeng);
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::APSInt* RangeConstraintManager::getSymVal(const ProgramState *St,
|
const llvm::APSInt* RangeConstraintManager::getSymVal(ProgramStateRef St,
|
||||||
SymbolRef sym) const {
|
SymbolRef sym) const {
|
||||||
const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
|
const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
|
||||||
return T ? T->getConcreteValue() : NULL;
|
return T ? T->getConcreteValue() : NULL;
|
||||||
|
@ -265,8 +265,8 @@ const llvm::APSInt* RangeConstraintManager::getSymVal(const ProgramState *St,
|
||||||
|
|
||||||
/// Scan all symbols referenced by the constraints. If the symbol is not alive
|
/// Scan all symbols referenced by the constraints. If the symbol is not alive
|
||||||
/// as marked in LSymbols, mark it as dead in DSymbols.
|
/// as marked in LSymbols, mark it as dead in DSymbols.
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::removeDeadBindings(const ProgramState *state,
|
RangeConstraintManager::removeDeadBindings(ProgramStateRef state,
|
||||||
SymbolReaper& SymReaper) {
|
SymbolReaper& SymReaper) {
|
||||||
|
|
||||||
ConstraintRangeTy CR = state->get<ConstraintRange>();
|
ConstraintRangeTy CR = state->get<ConstraintRange>();
|
||||||
|
@ -282,7 +282,7 @@ RangeConstraintManager::removeDeadBindings(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeSet
|
RangeSet
|
||||||
RangeConstraintManager::GetRange(const ProgramState *state, SymbolRef sym) {
|
RangeConstraintManager::GetRange(ProgramStateRef state, SymbolRef sym) {
|
||||||
if (ConstraintRangeTy::data_type* V = state->get<ConstraintRange>(sym))
|
if (ConstraintRangeTy::data_type* V = state->get<ConstraintRange>(sym))
|
||||||
return *V;
|
return *V;
|
||||||
|
|
||||||
|
@ -305,8 +305,8 @@ RangeConstraintManager::GetRange(const ProgramState *state, SymbolRef sym) {
|
||||||
// As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
|
// As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
|
||||||
// UINT_MAX, 0, 1, and 2.
|
// UINT_MAX, 0, 1, and 2.
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymNE(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymNE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
BasicValueFactory &BV = state->getBasicVals();
|
BasicValueFactory &BV = state->getBasicVals();
|
||||||
|
@ -322,8 +322,8 @@ RangeConstraintManager::assumeSymNE(const ProgramState *state, SymbolRef sym,
|
||||||
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymEQ(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymEQ(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
// [Int-Adjustment, Int-Adjustment]
|
// [Int-Adjustment, Int-Adjustment]
|
||||||
|
@ -333,8 +333,8 @@ RangeConstraintManager::assumeSymEQ(const ProgramState *state, SymbolRef sym,
|
||||||
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymLT(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymLT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
BasicValueFactory &BV = state->getBasicVals();
|
BasicValueFactory &BV = state->getBasicVals();
|
||||||
|
@ -354,8 +354,8 @@ RangeConstraintManager::assumeSymLT(const ProgramState *state, SymbolRef sym,
|
||||||
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymGT(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymGT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
BasicValueFactory &BV = state->getBasicVals();
|
BasicValueFactory &BV = state->getBasicVals();
|
||||||
|
@ -375,8 +375,8 @@ RangeConstraintManager::assumeSymGT(const ProgramState *state, SymbolRef sym,
|
||||||
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymGE(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymGE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
BasicValueFactory &BV = state->getBasicVals();
|
BasicValueFactory &BV = state->getBasicVals();
|
||||||
|
@ -397,8 +397,8 @@ RangeConstraintManager::assumeSymGE(const ProgramState *state, SymbolRef sym,
|
||||||
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState*
|
ProgramStateRef
|
||||||
RangeConstraintManager::assumeSymLE(const ProgramState *state, SymbolRef sym,
|
RangeConstraintManager::assumeSymLE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& Int,
|
const llvm::APSInt& Int,
|
||||||
const llvm::APSInt& Adjustment) {
|
const llvm::APSInt& Adjustment) {
|
||||||
BasicValueFactory &BV = state->getBasicVals();
|
BasicValueFactory &BV = state->getBasicVals();
|
||||||
|
@ -423,7 +423,7 @@ RangeConstraintManager::assumeSymLE(const ProgramState *state, SymbolRef sym,
|
||||||
// Pretty-printing.
|
// Pretty-printing.
|
||||||
//===------------------------------------------------------------------------===/
|
//===------------------------------------------------------------------------===/
|
||||||
|
|
||||||
void RangeConstraintManager::print(const ProgramState *St, raw_ostream &Out,
|
void RangeConstraintManager::print(ProgramStateRef St, raw_ostream &Out,
|
||||||
const char* nl, const char *sep) {
|
const char* nl, const char *sep) {
|
||||||
|
|
||||||
ConstraintRangeTy Ranges = St->get<ConstraintRange>();
|
ConstraintRangeTy Ranges = St->get<ConstraintRange>();
|
||||||
|
|
|
@ -379,7 +379,7 @@ public: // Part of public interface to class.
|
||||||
StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
|
StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
|
||||||
SymbolReaper& SymReaper);
|
SymbolReaper& SymReaper);
|
||||||
|
|
||||||
StoreRef enterStackFrame(const ProgramState *state,
|
StoreRef enterStackFrame(ProgramStateRef state,
|
||||||
const LocationContext *callerCtx,
|
const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx);
|
const StackFrameContext *calleeCtx);
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ public: // Part of public interface to class.
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
|
|
||||||
// FIXME: This method will soon be eliminated; see the note in Store.h.
|
// FIXME: This method will soon be eliminated; see the note in Store.h.
|
||||||
DefinedOrUnknownSVal getSizeInElements(const ProgramState *state,
|
DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
|
||||||
const MemRegion* R, QualType EleTy);
|
const MemRegion* R, QualType EleTy);
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
|
@ -796,7 +796,7 @@ StoreRef RegionStoreManager::invalidateRegions(Store store,
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
DefinedOrUnknownSVal
|
DefinedOrUnknownSVal
|
||||||
RegionStoreManager::getSizeInElements(const ProgramState *state,
|
RegionStoreManager::getSizeInElements(ProgramStateRef state,
|
||||||
const MemRegion *R,
|
const MemRegion *R,
|
||||||
QualType EleTy) {
|
QualType EleTy) {
|
||||||
SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
|
SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
|
||||||
|
@ -1858,7 +1858,7 @@ StoreRef RegionStoreManager::removeDeadBindings(Store store,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StoreRef RegionStoreManager::enterStackFrame(const ProgramState *state,
|
StoreRef RegionStoreManager::enterStackFrame(ProgramStateRef state,
|
||||||
const LocationContext *callerCtx,
|
const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx)
|
const StackFrameContext *calleeCtx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -169,7 +169,7 @@ DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
SVal SValBuilder::makeGenericVal(const ProgramState *State,
|
SVal SValBuilder::makeGenericVal(ProgramStateRef State,
|
||||||
BinaryOperator::Opcode Op,
|
BinaryOperator::Opcode Op,
|
||||||
NonLoc LHS, NonLoc RHS,
|
NonLoc LHS, NonLoc RHS,
|
||||||
QualType ResultTy) {
|
QualType ResultTy) {
|
||||||
|
@ -196,7 +196,7 @@ SVal SValBuilder::makeGenericVal(const ProgramState *State,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SVal SValBuilder::evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
|
SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
SVal lhs, SVal rhs, QualType type) {
|
SVal lhs, SVal rhs, QualType type) {
|
||||||
|
|
||||||
if (lhs.isUndef() || rhs.isUndef())
|
if (lhs.isUndef() || rhs.isUndef())
|
||||||
|
@ -224,7 +224,7 @@ SVal SValBuilder::evalBinOp(const ProgramState *state, BinaryOperator::Opcode op
|
||||||
return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type);
|
return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinedOrUnknownSVal SValBuilder::evalEQ(const ProgramState *state,
|
DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
|
||||||
DefinedOrUnknownSVal lhs,
|
DefinedOrUnknownSVal lhs,
|
||||||
DefinedOrUnknownSVal rhs) {
|
DefinedOrUnknownSVal rhs) {
|
||||||
return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs,
|
return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs,
|
||||||
|
|
|
@ -54,7 +54,7 @@ bool SimpleConstraintManager::canReasonAbout(SVal X) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assume(const ProgramState *state,
|
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
|
||||||
DefinedSVal Cond,
|
DefinedSVal Cond,
|
||||||
bool Assumption) {
|
bool Assumption) {
|
||||||
if (isa<NonLoc>(Cond))
|
if (isa<NonLoc>(Cond))
|
||||||
|
@ -63,13 +63,13 @@ const ProgramState *SimpleConstraintManager::assume(const ProgramState *state,
|
||||||
return assume(state, cast<Loc>(Cond), Assumption);
|
return assume(state, cast<Loc>(Cond), Assumption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assume(const ProgramState *state, Loc cond,
|
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state, Loc cond,
|
||||||
bool assumption) {
|
bool assumption) {
|
||||||
state = assumeAux(state, cond, assumption);
|
state = assumeAux(state, cond, assumption);
|
||||||
return SU.processAssume(state, cond, assumption);
|
return SU.processAssume(state, cond, assumption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assumeAux(const ProgramState *state,
|
ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
|
||||||
Loc Cond, bool Assumption) {
|
Loc Cond, bool Assumption) {
|
||||||
|
|
||||||
BasicValueFactory &BasicVals = state->getBasicVals();
|
BasicValueFactory &BasicVals = state->getBasicVals();
|
||||||
|
@ -111,7 +111,7 @@ const ProgramState *SimpleConstraintManager::assumeAux(const ProgramState *state
|
||||||
} // end switch
|
} // end switch
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assume(const ProgramState *state,
|
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
|
||||||
NonLoc cond,
|
NonLoc cond,
|
||||||
bool assumption) {
|
bool assumption) {
|
||||||
state = assumeAux(state, cond, assumption);
|
state = assumeAux(state, cond, assumption);
|
||||||
|
@ -134,8 +134,8 @@ static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assumeAuxForSymbol(
|
ProgramStateRef SimpleConstraintManager::assumeAuxForSymbol(
|
||||||
const ProgramState *State,
|
ProgramStateRef State,
|
||||||
SymbolRef Sym,
|
SymbolRef Sym,
|
||||||
bool Assumption) {
|
bool Assumption) {
|
||||||
QualType T = State->getSymbolManager().getType(Sym);
|
QualType T = State->getSymbolManager().getType(Sym);
|
||||||
|
@ -146,7 +146,7 @@ const ProgramState *SimpleConstraintManager::assumeAuxForSymbol(
|
||||||
return assumeSymEQ(State, Sym, zero, zero);
|
return assumeSymEQ(State, Sym, zero, zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assumeAux(const ProgramState *state,
|
ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
|
||||||
NonLoc Cond,
|
NonLoc Cond,
|
||||||
bool Assumption) {
|
bool Assumption) {
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ static llvm::APSInt computeAdjustment(const SymExpr *LHS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramState *SimpleConstraintManager::assumeSymRel(const ProgramState *state,
|
ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef state,
|
||||||
const SymExpr *LHS,
|
const SymExpr *LHS,
|
||||||
BinaryOperator::Opcode op,
|
BinaryOperator::Opcode op,
|
||||||
const llvm::APSInt& Int) {
|
const llvm::APSInt& Int) {
|
||||||
|
|
|
@ -31,14 +31,14 @@ public:
|
||||||
// Common implementation for the interface provided by ConstraintManager.
|
// Common implementation for the interface provided by ConstraintManager.
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
|
|
||||||
const ProgramState *assume(const ProgramState *state, DefinedSVal Cond,
|
ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond,
|
||||||
bool Assumption);
|
bool Assumption);
|
||||||
|
|
||||||
const ProgramState *assume(const ProgramState *state, Loc Cond, bool Assumption);
|
ProgramStateRef assume(ProgramStateRef state, Loc Cond, bool Assumption);
|
||||||
|
|
||||||
const ProgramState *assume(const ProgramState *state, NonLoc Cond, bool Assumption);
|
ProgramStateRef assume(ProgramStateRef state, NonLoc Cond, bool Assumption);
|
||||||
|
|
||||||
const ProgramState *assumeSymRel(const ProgramState *state,
|
ProgramStateRef assumeSymRel(ProgramStateRef state,
|
||||||
const SymExpr *LHS,
|
const SymExpr *LHS,
|
||||||
BinaryOperator::Opcode op,
|
BinaryOperator::Opcode op,
|
||||||
const llvm::APSInt& Int);
|
const llvm::APSInt& Int);
|
||||||
|
@ -51,27 +51,27 @@ protected:
|
||||||
|
|
||||||
// Each of these is of the form "$sym+Adj <> V", where "<>" is the comparison
|
// Each of these is of the form "$sym+Adj <> V", where "<>" is the comparison
|
||||||
// operation for the method being invoked.
|
// operation for the method being invoked.
|
||||||
virtual const ProgramState *assumeSymNE(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymNE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
virtual const ProgramState *assumeSymEQ(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymEQ(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
virtual const ProgramState *assumeSymLT(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymLT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
virtual const ProgramState *assumeSymGT(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymGT(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
virtual const ProgramState *assumeSymLE(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymLE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
virtual const ProgramState *assumeSymGE(const ProgramState *state, SymbolRef sym,
|
virtual ProgramStateRef assumeSymGE(ProgramStateRef state, SymbolRef sym,
|
||||||
const llvm::APSInt& V,
|
const llvm::APSInt& V,
|
||||||
const llvm::APSInt& Adjustment) = 0;
|
const llvm::APSInt& Adjustment) = 0;
|
||||||
|
|
||||||
|
@ -81,15 +81,15 @@ protected:
|
||||||
|
|
||||||
bool canReasonAbout(SVal X) const;
|
bool canReasonAbout(SVal X) const;
|
||||||
|
|
||||||
const ProgramState *assumeAux(const ProgramState *state,
|
ProgramStateRef assumeAux(ProgramStateRef state,
|
||||||
Loc Cond,
|
Loc Cond,
|
||||||
bool Assumption);
|
bool Assumption);
|
||||||
|
|
||||||
const ProgramState *assumeAux(const ProgramState *state,
|
ProgramStateRef assumeAux(ProgramStateRef state,
|
||||||
NonLoc Cond,
|
NonLoc Cond,
|
||||||
bool Assumption);
|
bool Assumption);
|
||||||
|
|
||||||
const ProgramState *assumeAuxForSymbol(const ProgramState *State,
|
ProgramStateRef assumeAuxForSymbol(ProgramStateRef State,
|
||||||
SymbolRef Sym,
|
SymbolRef Sym,
|
||||||
bool Assumption);
|
bool Assumption);
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,16 +32,16 @@ public:
|
||||||
|
|
||||||
virtual SVal evalMinus(NonLoc val);
|
virtual SVal evalMinus(NonLoc val);
|
||||||
virtual SVal evalComplement(NonLoc val);
|
virtual SVal evalComplement(NonLoc val);
|
||||||
virtual SVal evalBinOpNN(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
NonLoc lhs, NonLoc rhs, QualType resultTy);
|
NonLoc lhs, NonLoc rhs, QualType resultTy);
|
||||||
virtual SVal evalBinOpLL(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
Loc lhs, Loc rhs, QualType resultTy);
|
Loc lhs, Loc rhs, QualType resultTy);
|
||||||
virtual SVal evalBinOpLN(const ProgramState *state, BinaryOperator::Opcode op,
|
virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
|
||||||
Loc lhs, NonLoc rhs, QualType resultTy);
|
Loc lhs, NonLoc rhs, QualType resultTy);
|
||||||
|
|
||||||
/// getKnownValue - evaluates a given SVal. If the SVal has only one possible
|
/// getKnownValue - evaluates a given SVal. If the SVal has only one possible
|
||||||
/// (integer) value, that value is returned. Otherwise, returns NULL.
|
/// (integer) value, that value is returned. Otherwise, returns NULL.
|
||||||
virtual const llvm::APSInt *getKnownValue(const ProgramState *state, SVal V);
|
virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal V);
|
||||||
|
|
||||||
SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
|
SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
|
||||||
const llvm::APSInt &RHS, QualType resultTy);
|
const llvm::APSInt &RHS, QualType resultTy);
|
||||||
|
@ -276,7 +276,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
|
||||||
return makeNonLoc(LHS, op, RHS, resultTy);
|
return makeNonLoc(LHS, op, RHS, resultTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
|
SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
|
||||||
BinaryOperator::Opcode op,
|
BinaryOperator::Opcode op,
|
||||||
NonLoc lhs, NonLoc rhs,
|
NonLoc lhs, NonLoc rhs,
|
||||||
QualType resultTy) {
|
QualType resultTy) {
|
||||||
|
@ -547,7 +547,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: all this logic will change if/when we have MemRegion::getLocation().
|
// FIXME: all this logic will change if/when we have MemRegion::getLocation().
|
||||||
SVal SimpleSValBuilder::evalBinOpLL(const ProgramState *state,
|
SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
|
||||||
BinaryOperator::Opcode op,
|
BinaryOperator::Opcode op,
|
||||||
Loc lhs, Loc rhs,
|
Loc lhs, Loc rhs,
|
||||||
QualType resultTy) {
|
QualType resultTy) {
|
||||||
|
@ -842,7 +842,7 @@ SVal SimpleSValBuilder::evalBinOpLL(const ProgramState *state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal SimpleSValBuilder::evalBinOpLN(const ProgramState *state,
|
SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
|
||||||
BinaryOperator::Opcode op,
|
BinaryOperator::Opcode op,
|
||||||
Loc lhs, NonLoc rhs, QualType resultTy) {
|
Loc lhs, NonLoc rhs, QualType resultTy) {
|
||||||
|
|
||||||
|
@ -936,7 +936,7 @@ SVal SimpleSValBuilder::evalBinOpLN(const ProgramState *state,
|
||||||
return UnknownVal();
|
return UnknownVal();
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::APSInt *SimpleSValBuilder::getKnownValue(const ProgramState *state,
|
const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
|
||||||
SVal V) {
|
SVal V) {
|
||||||
if (V.isUnknownOrUndef())
|
if (V.isUnknownOrUndef())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -22,7 +22,7 @@ StoreManager::StoreManager(ProgramStateManager &stateMgr)
|
||||||
: svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr),
|
: svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr),
|
||||||
MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {}
|
MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {}
|
||||||
|
|
||||||
StoreRef StoreManager::enterStackFrame(const ProgramState *state,
|
StoreRef StoreManager::enterStackFrame(ProgramStateRef state,
|
||||||
const LocationContext *callerCtx,
|
const LocationContext *callerCtx,
|
||||||
const StackFrameContext *calleeCtx) {
|
const StackFrameContext *calleeCtx) {
|
||||||
return StoreRef(state->getStore(), *this);
|
return StoreRef(state->getStore(), *this);
|
||||||
|
|
Loading…
Reference in New Issue