зеркало из https://github.com/microsoft/clang-1.git
As GRState seems general enough, it is time to merge some template classes
and their impl base classes. This can greatly simply some code of the core analysis engine. This patch merges ExplodedNodeImpl into ExplodedNode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78270 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a10f7eabea
Коммит
c5619d901a
|
@ -48,8 +48,8 @@ class ParentMap;
|
|||
class BugReporterVisitor {
|
||||
public:
|
||||
virtual ~BugReporterVisitor();
|
||||
virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode<GRState>* PrevN,
|
||||
virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
|
||||
const ExplodedNode* PrevN,
|
||||
BugReporterContext& BRC) = 0;
|
||||
|
||||
virtual bool isOwnedByReporterContext() { return true; }
|
||||
|
@ -61,7 +61,7 @@ protected:
|
|||
BugType& BT;
|
||||
std::string ShortDescription;
|
||||
std::string Description;
|
||||
const ExplodedNode<GRState> *EndNode;
|
||||
const ExplodedNode *EndNode;
|
||||
SourceRange R;
|
||||
|
||||
protected:
|
||||
|
@ -76,15 +76,15 @@ public:
|
|||
class NodeResolver {
|
||||
public:
|
||||
virtual ~NodeResolver() {}
|
||||
virtual const ExplodedNode<GRState>*
|
||||
getOriginalNode(const ExplodedNode<GRState>* N) = 0;
|
||||
virtual const ExplodedNode*
|
||||
getOriginalNode(const ExplodedNode* N) = 0;
|
||||
};
|
||||
|
||||
BugReport(BugType& bt, const char* desc, const ExplodedNode<GRState> *n)
|
||||
BugReport(BugType& bt, const char* desc, const ExplodedNode *n)
|
||||
: BT(bt), Description(desc), EndNode(n) {}
|
||||
|
||||
BugReport(BugType& bt, const char* shortDesc, const char* desc,
|
||||
const ExplodedNode<GRState> *n)
|
||||
const ExplodedNode *n)
|
||||
: BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
|
||||
|
||||
virtual ~BugReport();
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
BugType& getBugType() { return BT; }
|
||||
|
||||
// FIXME: Perhaps this should be moved into a subclass?
|
||||
const ExplodedNode<GRState>* getEndNode() const { return EndNode; }
|
||||
const ExplodedNode* getEndNode() const { return EndNode; }
|
||||
|
||||
// FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint
|
||||
// object.
|
||||
|
@ -116,7 +116,7 @@ public:
|
|||
|
||||
// FIXME: Perhaps move this into a subclass.
|
||||
virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
|
||||
/// getLocation - Return the "definitive" location of the reported bug.
|
||||
/// While a bug can span an entire path, usually there is a specific
|
||||
|
@ -128,12 +128,12 @@ public:
|
|||
virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
|
||||
const SourceRange*& end);
|
||||
|
||||
virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode<GRState>* PrevN,
|
||||
virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
|
||||
const ExplodedNode* PrevN,
|
||||
BugReporterContext& BR);
|
||||
|
||||
virtual void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N) {}
|
||||
const ExplodedNode* N) {}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -217,11 +217,11 @@ public:
|
|||
class RangedBugReport : public BugReport {
|
||||
std::vector<SourceRange> Ranges;
|
||||
public:
|
||||
RangedBugReport(BugType& D, const char* description, ExplodedNode<GRState> *n)
|
||||
RangedBugReport(BugType& D, const char* description, ExplodedNode *n)
|
||||
: BugReport(D, description, n) {}
|
||||
|
||||
RangedBugReport(BugType& D, const char *shortDescription,
|
||||
const char *description, ExplodedNode<GRState> *n)
|
||||
const char *description, ExplodedNode *n)
|
||||
: BugReport(D, shortDescription, description, n) {}
|
||||
|
||||
~RangedBugReport();
|
||||
|
@ -465,14 +465,14 @@ public:
|
|||
|
||||
namespace bugreporter {
|
||||
|
||||
const Stmt *GetDerefExpr(const ExplodedNode<GRState> *N);
|
||||
const Stmt *GetReceiverExpr(const ExplodedNode<GRState> *N);
|
||||
const Stmt *GetDenomExpr(const ExplodedNode<GRState> *N);
|
||||
const Stmt *GetCalleeExpr(const ExplodedNode<GRState> *N);
|
||||
const Stmt *GetRetValExpr(const ExplodedNode<GRState> *N);
|
||||
const Stmt *GetDerefExpr(const ExplodedNode *N);
|
||||
const Stmt *GetReceiverExpr(const ExplodedNode *N);
|
||||
const Stmt *GetDenomExpr(const ExplodedNode *N);
|
||||
const Stmt *GetCalleeExpr(const ExplodedNode *N);
|
||||
const Stmt *GetRetValExpr(const ExplodedNode *N);
|
||||
|
||||
void registerTrackNullOrUndefValue(BugReporterContext& BRC, const Stmt *S,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
|
||||
} // end namespace clang::bugreporter
|
||||
|
||||
|
|
|
@ -30,20 +30,20 @@ namespace clang {
|
|||
class GRExprEngine;
|
||||
|
||||
class CheckerContext {
|
||||
ExplodedNodeSet<GRState> &Dst;
|
||||
ExplodedNodeSet &Dst;
|
||||
GRStmtNodeBuilder<GRState> &B;
|
||||
GRExprEngine &Eng;
|
||||
ExplodedNode<GRState> *Pred;
|
||||
ExplodedNode *Pred;
|
||||
SaveAndRestore<bool> OldSink;
|
||||
SaveAndRestore<const void*> OldTag;
|
||||
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
|
||||
SaveOr OldHasGen;
|
||||
|
||||
public:
|
||||
CheckerContext(ExplodedNodeSet<GRState> &dst,
|
||||
CheckerContext(ExplodedNodeSet &dst,
|
||||
GRStmtNodeBuilder<GRState> &builder,
|
||||
GRExprEngine &eng,
|
||||
ExplodedNode<GRState> *pred,
|
||||
ExplodedNode *pred,
|
||||
const void *tag, bool preVisit)
|
||||
: Dst(dst), B(builder), Eng(eng), Pred(pred),
|
||||
OldSink(B.BuildSinks), OldTag(B.Tag),
|
||||
|
@ -62,17 +62,17 @@ public:
|
|||
ConstraintManager &getConstraintManager() {
|
||||
return Eng.getConstraintManager();
|
||||
}
|
||||
ExplodedNodeSet<GRState> &getNodeSet() { return Dst; }
|
||||
ExplodedNodeSet &getNodeSet() { return Dst; }
|
||||
GRStmtNodeBuilder<GRState> &getNodeBuilder() { return B; }
|
||||
ExplodedNode<GRState> *&getPredecessor() { return Pred; }
|
||||
ExplodedNode *&getPredecessor() { return Pred; }
|
||||
const GRState *getState() { return B.GetState(Pred); }
|
||||
|
||||
ExplodedNode<GRState> *generateNode(const Stmt* S,
|
||||
ExplodedNode *generateNode(const Stmt* S,
|
||||
const GRState *state) {
|
||||
return B.generateNode(S, state, Pred);
|
||||
}
|
||||
|
||||
void addTransition(ExplodedNode<GRState> *node) {
|
||||
void addTransition(ExplodedNode *node) {
|
||||
Dst.Add(node);
|
||||
}
|
||||
|
||||
|
@ -85,11 +85,11 @@ class Checker {
|
|||
private:
|
||||
friend class GRExprEngine;
|
||||
|
||||
void GR_Visit(ExplodedNodeSet<GRState> &Dst,
|
||||
void GR_Visit(ExplodedNodeSet &Dst,
|
||||
GRStmtNodeBuilder<GRState> &Builder,
|
||||
GRExprEngine &Eng,
|
||||
const Stmt *stmt,
|
||||
ExplodedNode<GRState> *Pred, bool isPrevisit) {
|
||||
ExplodedNode *Pred, bool isPrevisit) {
|
||||
CheckerContext C(Dst, Builder, Eng, Pred, getTag(), isPrevisit);
|
||||
assert(isPrevisit && "Only previsit supported for now.");
|
||||
_PreVisit(C, stmt);
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
|
||||
namespace clang {
|
||||
|
||||
class GRState;
|
||||
class GRCoreEngineImpl;
|
||||
class ExplodedNodeImpl;
|
||||
class ExplodedNode;
|
||||
class CFG;
|
||||
class ASTContext;
|
||||
|
||||
|
@ -45,7 +46,7 @@ class GREndPathNodebuilderImpl;
|
|||
// on top of these classes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class ExplodedNodeImpl : public llvm::FoldingSetNode {
|
||||
class ExplodedNode : public llvm::FoldingSetNode {
|
||||
protected:
|
||||
friend class ExplodedGraphImpl;
|
||||
friend class GRCoreEngineImpl;
|
||||
|
@ -68,8 +69,8 @@ protected:
|
|||
return reinterpret_cast<void*>(P & ~Mask);
|
||||
}
|
||||
|
||||
ExplodedNodeImpl* getNode() const {
|
||||
return reinterpret_cast<ExplodedNodeImpl*>(getPtr());
|
||||
ExplodedNode *getNode() const {
|
||||
return reinterpret_cast<ExplodedNode*>(getPtr());
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -77,15 +78,15 @@ protected:
|
|||
|
||||
~NodeGroup();
|
||||
|
||||
ExplodedNodeImpl** begin() const;
|
||||
ExplodedNode** begin() const;
|
||||
|
||||
ExplodedNodeImpl** end() const;
|
||||
ExplodedNode** end() const;
|
||||
|
||||
unsigned size() const;
|
||||
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
void addNode(ExplodedNodeImpl* N);
|
||||
void addNode(ExplodedNode* N);
|
||||
|
||||
void setFlag() {
|
||||
assert (P == 0);
|
||||
|
@ -102,30 +103,40 @@ protected:
|
|||
const ProgramPoint Location;
|
||||
|
||||
/// State - The state associated with this node.
|
||||
const void* State;
|
||||
const GRState* State;
|
||||
|
||||
/// Preds - The predecessors of this node.
|
||||
NodeGroup Preds;
|
||||
|
||||
/// Succs - The successors of this node.
|
||||
NodeGroup Succs;
|
||||
|
||||
/// Construct a ExplodedNodeImpl with the provided location and state.
|
||||
explicit ExplodedNodeImpl(const ProgramPoint& loc, const void* state)
|
||||
: Location(loc), State(state) {}
|
||||
|
||||
/// addPredeccessor - Adds a predecessor to the current node, and
|
||||
/// in tandem add this node as a successor of the other node.
|
||||
void addPredecessor(ExplodedNodeImpl* V);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
|
||||
: Location(loc), State(state) {}
|
||||
|
||||
/// getLocation - Returns the edge associated with the given node.
|
||||
ProgramPoint getLocation() const { return Location; }
|
||||
|
||||
|
||||
const GRState* getState() const {
|
||||
return State;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
|
||||
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ProgramPoint& Loc, const GRState* state);
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
Profile(ID, getLocation(), getState());
|
||||
}
|
||||
|
||||
/// addPredeccessor - Adds a predecessor to the current node, and
|
||||
/// in tandem add this node as a successor of the other node.
|
||||
void addPredecessor(ExplodedNode* V);
|
||||
|
||||
unsigned succ_size() const { return Succs.size(); }
|
||||
unsigned pred_size() const { return Preds.size(); }
|
||||
bool succ_empty() const { return Succs.empty(); }
|
||||
|
@ -133,59 +144,7 @@ public:
|
|||
|
||||
bool isSink() const { return Succs.getFlag(); }
|
||||
void markAsSink() { Succs.setFlag(); }
|
||||
|
||||
// For debugging.
|
||||
|
||||
public:
|
||||
|
||||
class Auditor {
|
||||
public:
|
||||
virtual ~Auditor();
|
||||
virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) = 0;
|
||||
};
|
||||
|
||||
static void SetAuditor(Auditor* A);
|
||||
};
|
||||
|
||||
|
||||
template <typename StateTy>
|
||||
struct GRTrait {
|
||||
static inline void Profile(llvm::FoldingSetNodeID& ID, const StateTy* St) {
|
||||
St->Profile(ID);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename StateTy>
|
||||
class ExplodedNode : public ExplodedNodeImpl {
|
||||
public:
|
||||
/// Construct a ExplodedNodeImpl with the given node ID, program edge,
|
||||
/// and state.
|
||||
explicit ExplodedNode(const ProgramPoint& loc, const StateTy* St)
|
||||
: ExplodedNodeImpl(loc, St) {}
|
||||
|
||||
/// getState - Returns the state associated with the node.
|
||||
inline const StateTy* getState() const {
|
||||
return static_cast<const StateTy*>(State);
|
||||
}
|
||||
|
||||
// Profiling (for FoldingSet).
|
||||
|
||||
static inline void Profile(llvm::FoldingSetNodeID& ID,
|
||||
const ProgramPoint& Loc,
|
||||
const StateTy* state) {
|
||||
ID.Add(Loc);
|
||||
GRTrait<StateTy>::Profile(ID, state);
|
||||
}
|
||||
|
||||
inline void Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
Profile(ID, getLocation(), getState());
|
||||
}
|
||||
|
||||
void addPredecessor(ExplodedNode* V) {
|
||||
ExplodedNodeImpl::addPredecessor(V);
|
||||
}
|
||||
|
||||
ExplodedNode* getFirstPred() {
|
||||
return pred_empty() ? NULL : *(pred_begin());
|
||||
}
|
||||
|
@ -200,8 +159,8 @@ public:
|
|||
typedef ExplodedNode** pred_iterator;
|
||||
typedef const ExplodedNode* const * const_pred_iterator;
|
||||
|
||||
pred_iterator pred_begin() { return (ExplodedNode**) Preds.begin(); }
|
||||
pred_iterator pred_end() { return (ExplodedNode**) Preds.end(); }
|
||||
pred_iterator pred_begin() { return Preds.begin(); }
|
||||
pred_iterator pred_end() { return Preds.end(); }
|
||||
|
||||
const_pred_iterator pred_begin() const {
|
||||
return const_cast<ExplodedNode*>(this)->pred_begin();
|
||||
|
@ -210,8 +169,8 @@ public:
|
|||
return const_cast<ExplodedNode*>(this)->pred_end();
|
||||
}
|
||||
|
||||
succ_iterator succ_begin() { return (ExplodedNode**) Succs.begin(); }
|
||||
succ_iterator succ_end() { return (ExplodedNode**) Succs.end(); }
|
||||
succ_iterator succ_begin() { return Succs.begin(); }
|
||||
succ_iterator succ_end() { return Succs.end(); }
|
||||
|
||||
const_succ_iterator succ_begin() const {
|
||||
return const_cast<ExplodedNode*>(this)->succ_begin();
|
||||
|
@ -219,6 +178,26 @@ public:
|
|||
const_succ_iterator succ_end() const {
|
||||
return const_cast<ExplodedNode*>(this)->succ_end();
|
||||
}
|
||||
|
||||
// For debugging.
|
||||
|
||||
public:
|
||||
|
||||
class Auditor {
|
||||
public:
|
||||
virtual ~Auditor();
|
||||
virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst) = 0;
|
||||
};
|
||||
|
||||
static void SetAuditor(Auditor* A);
|
||||
};
|
||||
|
||||
|
||||
template <typename StateTy>
|
||||
struct GRTrait {
|
||||
static inline void Profile(llvm::FoldingSetNodeID& ID, const StateTy* St) {
|
||||
St->Profile(ID);
|
||||
}
|
||||
};
|
||||
|
||||
class InterExplodedGraphMapImpl;
|
||||
|
@ -233,8 +212,8 @@ protected:
|
|||
friend class GREndPathNodeBuilderImpl;
|
||||
|
||||
// Type definitions.
|
||||
typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
|
||||
typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
|
||||
typedef llvm::SmallVector<ExplodedNode*,2> RootsTy;
|
||||
typedef llvm::SmallVector<ExplodedNode*,10> EndNodesTy;
|
||||
|
||||
/// Roots - The roots of the simulation graph. Usually there will be only
|
||||
/// one, but clients are free to establish multiple subgraphs within a single
|
||||
|
@ -265,20 +244,20 @@ protected:
|
|||
/// getNodeImpl - Retrieve the node associated with a (Location,State)
|
||||
/// pair, where 'State' is represented as an opaque void*. This method
|
||||
/// is intended to be used only by GRCoreEngineImpl.
|
||||
virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
|
||||
virtual ExplodedNode* getNodeImpl(const ProgramPoint& L,
|
||||
const void* State,
|
||||
bool* IsNew) = 0;
|
||||
|
||||
virtual ExplodedGraphImpl* MakeEmptyGraph() const = 0;
|
||||
|
||||
/// addRoot - Add an untyped node to the set of roots.
|
||||
ExplodedNodeImpl* addRoot(ExplodedNodeImpl* V) {
|
||||
ExplodedNode* addRoot(ExplodedNode* V) {
|
||||
Roots.push_back(V);
|
||||
return V;
|
||||
}
|
||||
|
||||
/// addEndOfPath - Add an untyped node to the set of EOP nodes.
|
||||
ExplodedNodeImpl* addEndOfPath(ExplodedNodeImpl* V) {
|
||||
ExplodedNode* addEndOfPath(ExplodedNode* V) {
|
||||
EndNodes.push_back(V);
|
||||
return V;
|
||||
}
|
||||
|
@ -307,22 +286,21 @@ public:
|
|||
return llvm::dyn_cast<FunctionDecl>(&CodeDecl);
|
||||
}
|
||||
|
||||
typedef llvm::DenseMap<const ExplodedNodeImpl*, ExplodedNodeImpl*> NodeMap;
|
||||
typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
|
||||
|
||||
ExplodedGraphImpl* Trim(const ExplodedNodeImpl* const * NBeg,
|
||||
const ExplodedNodeImpl* const * NEnd,
|
||||
ExplodedGraphImpl* Trim(const ExplodedNode* const * NBeg,
|
||||
const ExplodedNode* const * NEnd,
|
||||
InterExplodedGraphMapImpl *M,
|
||||
llvm::DenseMap<const void*, const void*> *InverseMap)
|
||||
const;
|
||||
llvm::DenseMap<const void*, const void*> *InverseMap) const;
|
||||
};
|
||||
|
||||
class InterExplodedGraphMapImpl {
|
||||
llvm::DenseMap<const ExplodedNodeImpl*, ExplodedNodeImpl*> M;
|
||||
llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
|
||||
friend class ExplodedGraphImpl;
|
||||
void add(const ExplodedNodeImpl* From, ExplodedNodeImpl* To);
|
||||
void add(const ExplodedNode* From, ExplodedNode* To);
|
||||
|
||||
protected:
|
||||
ExplodedNodeImpl* getMappedImplNode(const ExplodedNodeImpl* N) const;
|
||||
ExplodedNode* getMappedImplNode(const ExplodedNode* N) const;
|
||||
|
||||
InterExplodedGraphMapImpl();
|
||||
public:
|
||||
|
@ -333,14 +311,13 @@ public:
|
|||
// Type-specialized ExplodedGraph classes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <typename STATE>
|
||||
class InterExplodedGraphMap : public InterExplodedGraphMapImpl {
|
||||
public:
|
||||
InterExplodedGraphMap() {};
|
||||
~InterExplodedGraphMap() {};
|
||||
|
||||
ExplodedNode<STATE>* getMappedNode(const ExplodedNode<STATE>* N) const {
|
||||
return static_cast<ExplodedNode<STATE>*>(getMappedImplNode(N));
|
||||
ExplodedNode* getMappedNode(const ExplodedNode* N) const {
|
||||
return static_cast<ExplodedNode*>(getMappedImplNode(N));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -348,21 +325,21 @@ template <typename STATE>
|
|||
class ExplodedGraph : public ExplodedGraphImpl {
|
||||
public:
|
||||
typedef STATE StateTy;
|
||||
typedef ExplodedNode<StateTy> NodeTy;
|
||||
typedef ExplodedNode NodeTy;
|
||||
typedef llvm::FoldingSet<NodeTy> AllNodesTy;
|
||||
|
||||
protected:
|
||||
virtual ExplodedNode* getNodeImpl(const ProgramPoint& L,
|
||||
const void* State,
|
||||
bool* IsNew) {
|
||||
|
||||
return getNode(L, static_cast<const StateTy*>(State), IsNew);
|
||||
}
|
||||
|
||||
/// Nodes - The nodes in the graph.
|
||||
AllNodesTy Nodes;
|
||||
|
||||
protected:
|
||||
virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
|
||||
const void* State,
|
||||
bool* IsNew) {
|
||||
|
||||
return getNode(L, static_cast<const StateTy*>(State), IsNew);
|
||||
}
|
||||
|
||||
virtual ExplodedGraphImpl* MakeEmptyGraph() const {
|
||||
return new ExplodedGraph(cfg, CodeDecl, Ctx);
|
||||
}
|
||||
|
@ -375,7 +352,7 @@ public:
|
|||
/// 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
|
||||
/// the node was freshly created.
|
||||
NodeTy* getNode(const ProgramPoint& L, const StateTy* State,
|
||||
NodeTy* getNode(const ProgramPoint& L, const GRState* State,
|
||||
bool* IsNew = NULL) {
|
||||
|
||||
// Profile 'State' to determine if we already have an existing node.
|
||||
|
@ -459,23 +436,22 @@ public:
|
|||
return const_cast<ExplodedGraph>(this)->eop_end();
|
||||
}
|
||||
|
||||
std::pair<ExplodedGraph*, InterExplodedGraphMap<STATE>*>
|
||||
std::pair<ExplodedGraph*, InterExplodedGraphMap*>
|
||||
Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
|
||||
llvm::DenseMap<const void*, const void*> *InverseMap = 0) const {
|
||||
|
||||
if (NBeg == NEnd)
|
||||
return std::make_pair((ExplodedGraph*) 0,
|
||||
(InterExplodedGraphMap<STATE>*) 0);
|
||||
(InterExplodedGraphMap*) 0);
|
||||
|
||||
assert (NBeg < NEnd);
|
||||
|
||||
const ExplodedNodeImpl* const* NBegImpl =
|
||||
(const ExplodedNodeImpl* const*) NBeg;
|
||||
const ExplodedNodeImpl* const* NEndImpl =
|
||||
(const ExplodedNodeImpl* const*) NEnd;
|
||||
const ExplodedNode* const* NBegImpl =
|
||||
(const ExplodedNode* const*) NBeg;
|
||||
const ExplodedNode* const* NEndImpl =
|
||||
(const ExplodedNode* const*) NEnd;
|
||||
|
||||
llvm::OwningPtr<InterExplodedGraphMap<STATE> >
|
||||
M(new InterExplodedGraphMap<STATE>());
|
||||
llvm::OwningPtr<InterExplodedGraphMap> M(new InterExplodedGraphMap());
|
||||
|
||||
ExplodedGraphImpl* G = ExplodedGraphImpl::Trim(NBegImpl, NEndImpl, M.get(),
|
||||
InverseMap);
|
||||
|
@ -484,23 +460,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <typename StateTy>
|
||||
class ExplodedNodeSet {
|
||||
|
||||
typedef ExplodedNode<StateTy> NodeTy;
|
||||
typedef llvm::SmallPtrSet<NodeTy*,5> ImplTy;
|
||||
typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
|
||||
ImplTy Impl;
|
||||
|
||||
public:
|
||||
ExplodedNodeSet(NodeTy* N) {
|
||||
assert (N && !static_cast<ExplodedNodeImpl*>(N)->isSink());
|
||||
ExplodedNodeSet(ExplodedNode* N) {
|
||||
assert (N && !static_cast<ExplodedNode*>(N)->isSink());
|
||||
Impl.insert(N);
|
||||
}
|
||||
|
||||
ExplodedNodeSet() {}
|
||||
|
||||
inline void Add(NodeTy* N) {
|
||||
if (N && !static_cast<ExplodedNodeImpl*>(N)->isSink()) Impl.insert(N);
|
||||
inline void Add(ExplodedNode* N) {
|
||||
if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
|
||||
}
|
||||
|
||||
ExplodedNodeSet& operator=(const ExplodedNodeSet &X) {
|
||||
|
@ -508,8 +481,8 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
typedef typename ImplTy::iterator iterator;
|
||||
typedef typename ImplTy::const_iterator const_iterator;
|
||||
typedef ImplTy::iterator iterator;
|
||||
typedef ImplTy::const_iterator const_iterator;
|
||||
|
||||
inline unsigned size() const { return Impl.size(); }
|
||||
inline bool empty() const { return Impl.empty(); }
|
||||
|
@ -528,10 +501,9 @@ public:
|
|||
// GraphTraits
|
||||
|
||||
namespace llvm {
|
||||
template<typename StateTy>
|
||||
struct GraphTraits<clang::ExplodedNode<StateTy>*> {
|
||||
typedef clang::ExplodedNode<StateTy> NodeType;
|
||||
typedef typename NodeType::succ_iterator ChildIteratorType;
|
||||
template<> struct GraphTraits<clang::ExplodedNode*> {
|
||||
typedef clang::ExplodedNode NodeType;
|
||||
typedef NodeType::succ_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<NodeType*> nodes_iterator;
|
||||
|
||||
static inline NodeType* getEntryNode(NodeType* N) {
|
||||
|
@ -555,10 +527,9 @@ namespace llvm {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename StateTy>
|
||||
struct GraphTraits<const clang::ExplodedNode<StateTy>*> {
|
||||
typedef const clang::ExplodedNode<StateTy> NodeType;
|
||||
typedef typename NodeType::succ_iterator ChildIteratorType;
|
||||
template<> struct GraphTraits<const clang::ExplodedNode*> {
|
||||
typedef const clang::ExplodedNode NodeType;
|
||||
typedef NodeType::const_succ_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<NodeType*> nodes_iterator;
|
||||
|
||||
static inline NodeType* getEntryNode(NodeType* N) {
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace clang {
|
|||
template <typename STATE>
|
||||
class GRAuditor {
|
||||
public:
|
||||
typedef ExplodedNode<STATE> NodeTy;
|
||||
typedef ExplodedNode NodeTy;
|
||||
typedef typename STATE::ManagerTy ManagerTy;
|
||||
|
||||
virtual ~GRAuditor() {}
|
||||
|
|
|
@ -62,7 +62,7 @@ protected:
|
|||
GRBlockCounter::Factory BCounterFactory;
|
||||
|
||||
void GenerateNode(const ProgramPoint& Loc, const void* State,
|
||||
ExplodedNodeImpl* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
/// getInitialState - Gets the void* representing the initial 'state'
|
||||
/// of the analysis. This is simply a wrapper (implemented
|
||||
|
@ -70,14 +70,14 @@ protected:
|
|||
/// state returned by the checker object.
|
||||
virtual const void* getInitialState() = 0;
|
||||
|
||||
void HandleBlockEdge(const BlockEdge& E, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockExit(CFGBlock* B, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
|
||||
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
|
||||
void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
|
||||
void HandlePostStmt(const PostStmt& S, CFGBlock* B,
|
||||
unsigned StmtIdx, ExplodedNodeImpl *Pred);
|
||||
unsigned StmtIdx, ExplodedNode *Pred);
|
||||
|
||||
void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
|
||||
ExplodedNodeImpl* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
virtual void ProcessEndPath(GREndPathNodeBuilderImpl& Builder) = 0;
|
||||
|
||||
|
@ -115,23 +115,23 @@ class GRStmtNodeBuilderImpl {
|
|||
GRCoreEngineImpl& Eng;
|
||||
CFGBlock& B;
|
||||
const unsigned Idx;
|
||||
ExplodedNodeImpl* Pred;
|
||||
ExplodedNodeImpl* LastNode;
|
||||
ExplodedNode* Pred;
|
||||
ExplodedNode* LastNode;
|
||||
|
||||
typedef llvm::SmallPtrSet<ExplodedNodeImpl*,5> DeferredTy;
|
||||
typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
|
||||
DeferredTy Deferred;
|
||||
|
||||
void GenerateAutoTransition(ExplodedNodeImpl* N);
|
||||
void GenerateAutoTransition(ExplodedNode* N);
|
||||
|
||||
public:
|
||||
GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
|
||||
ExplodedNodeImpl* N, GRCoreEngineImpl* e);
|
||||
ExplodedNode* N, GRCoreEngineImpl* e);
|
||||
|
||||
~GRStmtNodeBuilderImpl();
|
||||
|
||||
ExplodedNodeImpl* getBasePredecessor() const { return Pred; }
|
||||
ExplodedNode* getBasePredecessor() const { return Pred; }
|
||||
|
||||
ExplodedNodeImpl* getLastNode() const {
|
||||
ExplodedNode* getLastNode() const {
|
||||
return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
|
||||
}
|
||||
|
||||
|
@ -141,27 +141,27 @@ public:
|
|||
return getBlockCounter().getNumVisited(B.getBlockID());
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
generateNodeImpl(const ProgramPoint &PP, const void* State,
|
||||
ExplodedNodeImpl* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
ExplodedNodeImpl*
|
||||
generateNodeImpl(const Stmt* S, const void* State, ExplodedNodeImpl* Pred,
|
||||
ExplodedNode*
|
||||
generateNodeImpl(const Stmt* S, const void* State, ExplodedNode* Pred,
|
||||
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
|
||||
const void *tag = 0);
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
generateNodeImpl(const Stmt* S, const void* State,
|
||||
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
|
||||
const void *tag = 0) {
|
||||
ExplodedNodeImpl* N = getLastNode();
|
||||
ExplodedNode* N = getLastNode();
|
||||
assert (N && "Predecessor of new node is infeasible.");
|
||||
return generateNodeImpl(S, State, N, K, tag);
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
generateNodeImpl(const Stmt* S, const void* State, const void *tag = 0) {
|
||||
ExplodedNodeImpl* N = getLastNode();
|
||||
ExplodedNode* N = getLastNode();
|
||||
assert (N && "Predecessor of new node is infeasible.");
|
||||
return generateNodeImpl(S, State, N, ProgramPoint::PostStmtKind, tag);
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class GRStmtNodeBuilder {
|
|||
public:
|
||||
typedef STATE StateTy;
|
||||
typedef typename StateTy::ManagerTy StateManagerTy;
|
||||
typedef ExplodedNode<StateTy> NodeTy;
|
||||
typedef ExplodedNode NodeTy;
|
||||
|
||||
private:
|
||||
GRStmtNodeBuilderImpl& NB;
|
||||
|
@ -242,7 +242,7 @@ public:
|
|||
}
|
||||
|
||||
const StateTy* GetState(NodeTy* Pred) const {
|
||||
if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
|
||||
if ((ExplodedNode*) Pred == NB.getBasePredecessor())
|
||||
return CleanedState;
|
||||
else
|
||||
return Pred->getState();
|
||||
|
@ -252,12 +252,12 @@ public:
|
|||
CleanedState = St;
|
||||
}
|
||||
|
||||
NodeTy* MakeNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
|
||||
NodeTy* MakeNode(ExplodedNodeSet& Dst, Stmt* S,
|
||||
NodeTy* Pred, const StateTy* St) {
|
||||
return MakeNode(Dst, S, Pred, St, PointKind);
|
||||
}
|
||||
|
||||
NodeTy* MakeNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
|
||||
NodeTy* MakeNode(ExplodedNodeSet& Dst, Stmt* S,
|
||||
NodeTy* Pred, const StateTy* St, ProgramPoint::Kind K) {
|
||||
|
||||
const StateTy* PredState = GetState(Pred);
|
||||
|
@ -284,7 +284,7 @@ public:
|
|||
return N;
|
||||
}
|
||||
|
||||
NodeTy* MakeSinkNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
|
||||
NodeTy* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
|
||||
NodeTy* Pred, const StateTy* St) {
|
||||
bool Tmp = BuildSinks;
|
||||
BuildSinks = true;
|
||||
|
@ -305,9 +305,9 @@ class GRBranchNodeBuilderImpl {
|
|||
CFGBlock* Src;
|
||||
CFGBlock* DstT;
|
||||
CFGBlock* DstF;
|
||||
ExplodedNodeImpl* Pred;
|
||||
ExplodedNode* Pred;
|
||||
|
||||
typedef llvm::SmallVector<ExplodedNodeImpl*,3> DeferredTy;
|
||||
typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
|
||||
DeferredTy Deferred;
|
||||
|
||||
bool GeneratedTrue;
|
||||
|
@ -317,18 +317,18 @@ class GRBranchNodeBuilderImpl {
|
|||
|
||||
public:
|
||||
GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
|
||||
ExplodedNodeImpl* pred, GRCoreEngineImpl* e)
|
||||
ExplodedNode* pred, GRCoreEngineImpl* e)
|
||||
: Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
|
||||
GeneratedTrue(false), GeneratedFalse(false),
|
||||
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
|
||||
|
||||
~GRBranchNodeBuilderImpl();
|
||||
|
||||
ExplodedNodeImpl* getPredecessor() const { return Pred; }
|
||||
ExplodedNode* getPredecessor() const { return Pred; }
|
||||
const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
|
||||
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
|
||||
|
||||
ExplodedNodeImpl* generateNodeImpl(const void* State, bool branch);
|
||||
ExplodedNode* generateNodeImpl(const void* State, bool branch);
|
||||
|
||||
CFGBlock* getTargetBlock(bool branch) const {
|
||||
return branch ? DstT : DstF;
|
||||
|
@ -395,9 +395,9 @@ class GRIndirectGotoNodeBuilderImpl {
|
|||
CFGBlock* Src;
|
||||
CFGBlock& DispatchBlock;
|
||||
Expr* E;
|
||||
ExplodedNodeImpl* Pred;
|
||||
ExplodedNode* Pred;
|
||||
public:
|
||||
GRIndirectGotoNodeBuilderImpl(ExplodedNodeImpl* pred, CFGBlock* src,
|
||||
GRIndirectGotoNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src,
|
||||
Expr* e, CFGBlock* dispatch,
|
||||
GRCoreEngineImpl* eng)
|
||||
: Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
|
||||
|
@ -425,7 +425,7 @@ public:
|
|||
Iterator begin() { return Iterator(DispatchBlock.succ_begin()); }
|
||||
Iterator end() { return Iterator(DispatchBlock.succ_end()); }
|
||||
|
||||
ExplodedNodeImpl* generateNodeImpl(const Iterator& I, const void* State,
|
||||
ExplodedNode* generateNodeImpl(const Iterator& I, const void* State,
|
||||
bool isSink);
|
||||
|
||||
Expr* getTarget() const { return E; }
|
||||
|
@ -463,9 +463,9 @@ class GRSwitchNodeBuilderImpl {
|
|||
GRCoreEngineImpl& Eng;
|
||||
CFGBlock* Src;
|
||||
Expr* Condition;
|
||||
ExplodedNodeImpl* Pred;
|
||||
ExplodedNode* Pred;
|
||||
public:
|
||||
GRSwitchNodeBuilderImpl(ExplodedNodeImpl* pred, CFGBlock* src,
|
||||
GRSwitchNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src,
|
||||
Expr* condition, GRCoreEngineImpl* eng)
|
||||
: Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
|
||||
|
||||
|
@ -491,10 +491,10 @@ public:
|
|||
Iterator begin() { return Iterator(Src->succ_rbegin()+1); }
|
||||
Iterator end() { return Iterator(Src->succ_rend()); }
|
||||
|
||||
ExplodedNodeImpl* generateCaseStmtNodeImpl(const Iterator& I,
|
||||
ExplodedNode* generateCaseStmtNodeImpl(const Iterator& I,
|
||||
const void* State);
|
||||
|
||||
ExplodedNodeImpl* generateDefaultCaseNodeImpl(const void* State,
|
||||
ExplodedNode* generateDefaultCaseNodeImpl(const void* State,
|
||||
bool isSink);
|
||||
|
||||
Expr* getCondition() const { return Condition; }
|
||||
|
@ -536,17 +536,17 @@ public:
|
|||
class GREndPathNodeBuilderImpl {
|
||||
GRCoreEngineImpl& Eng;
|
||||
CFGBlock& B;
|
||||
ExplodedNodeImpl* Pred;
|
||||
ExplodedNode* Pred;
|
||||
bool HasGeneratedNode;
|
||||
|
||||
public:
|
||||
GREndPathNodeBuilderImpl(CFGBlock* b, ExplodedNodeImpl* N,
|
||||
GREndPathNodeBuilderImpl(CFGBlock* b, ExplodedNode* N,
|
||||
GRCoreEngineImpl* e)
|
||||
: Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
|
||||
|
||||
~GREndPathNodeBuilderImpl();
|
||||
|
||||
ExplodedNodeImpl* getPredecessor() const { return Pred; }
|
||||
ExplodedNode* getPredecessor() const { return Pred; }
|
||||
|
||||
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
|
||||
|
||||
|
@ -554,9 +554,9 @@ public:
|
|||
return getBlockCounter().getNumVisited(B.getBlockID());
|
||||
}
|
||||
|
||||
ExplodedNodeImpl* generateNodeImpl(const void* State,
|
||||
ExplodedNode* generateNodeImpl(const void* State,
|
||||
const void *tag = 0,
|
||||
ExplodedNodeImpl *P = 0);
|
||||
ExplodedNode *P = 0);
|
||||
|
||||
CFGBlock* getBlock() const { return &B; }
|
||||
};
|
||||
|
@ -565,7 +565,7 @@ public:
|
|||
template<typename STATE>
|
||||
class GREndPathNodeBuilder {
|
||||
typedef STATE StateTy;
|
||||
typedef ExplodedNode<StateTy> NodeTy;
|
||||
typedef ExplodedNode NodeTy;
|
||||
|
||||
GREndPathNodeBuilderImpl& NB;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
typedef GRIndirectGotoNodeBuilder<StateTy> IndirectGotoNodeBuilder;
|
||||
typedef GRSwitchNodeBuilder<StateTy> SwitchNodeBuilder;
|
||||
typedef GREndPathNodeBuilder<StateTy> EndPathNodeBuilder;
|
||||
typedef ExplodedNodeSet<StateTy> NodeSet;
|
||||
typedef ExplodedNodeSet NodeSet;
|
||||
|
||||
protected:
|
||||
GRCoreEngine<GRExprEngine> CoreEngine;
|
||||
|
|
|
@ -38,17 +38,17 @@ public:
|
|||
|
||||
// Calls.
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {}
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
ExplodedNode<GRState>* Pred) {}
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
// Stores.
|
||||
|
||||
|
@ -60,19 +60,19 @@ public:
|
|||
GREndPathNodeBuilder<GRState>& Builder) {}
|
||||
|
||||
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
ExplodedNode* Pred,
|
||||
Stmt* S, const GRState* state,
|
||||
SymbolReaper& SymReaper) {}
|
||||
|
||||
// Return statements.
|
||||
virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ReturnStmt* S,
|
||||
ExplodedNode<GRState>* Pred) {}
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
// Assumptions.
|
||||
virtual const GRState* EvalAssume(const GRState *state,
|
||||
|
|
|
@ -22,26 +22,26 @@ namespace clang {
|
|||
class ExplodedNodeImpl;
|
||||
|
||||
class GRWorkListUnit {
|
||||
ExplodedNodeImpl* Node;
|
||||
ExplodedNode* Node;
|
||||
GRBlockCounter Counter;
|
||||
CFGBlock* Block;
|
||||
unsigned BlockIdx;
|
||||
|
||||
public:
|
||||
GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C,
|
||||
GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
|
||||
CFGBlock* B, unsigned idx)
|
||||
: Node(N),
|
||||
Counter(C),
|
||||
Block(B),
|
||||
BlockIdx(idx) {}
|
||||
|
||||
explicit GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C)
|
||||
explicit GRWorkListUnit(ExplodedNode* N, GRBlockCounter C)
|
||||
: Node(N),
|
||||
Counter(C),
|
||||
Block(NULL),
|
||||
BlockIdx(0) {}
|
||||
|
||||
ExplodedNodeImpl* getNode() const { return Node; }
|
||||
ExplodedNode* getNode() const { return Node; }
|
||||
GRBlockCounter getBlockCounter() const { return Counter; }
|
||||
CFGBlock* getBlock() const { return Block; }
|
||||
unsigned getIndex() const { return BlockIdx; }
|
||||
|
@ -55,11 +55,11 @@ public:
|
|||
|
||||
virtual void Enqueue(const GRWorkListUnit& U) = 0;
|
||||
|
||||
void Enqueue(ExplodedNodeImpl* N, CFGBlock& B, unsigned idx) {
|
||||
void Enqueue(ExplodedNode* N, CFGBlock& B, unsigned idx) {
|
||||
Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
|
||||
}
|
||||
|
||||
void Enqueue(ExplodedNodeImpl* N) {
|
||||
void Enqueue(ExplodedNode* N) {
|
||||
Enqueue(GRWorkListUnit(N, CurrentCounter));
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
BasicObjCFoundationChecks(ASTContext& ctx, BugReporter& br)
|
||||
: BT(0), BR(br), Ctx(ctx) {}
|
||||
|
||||
bool Audit(ExplodedNode<GRState>* N, GRStateManager&);
|
||||
bool Audit(ExplodedNode* N, GRStateManager&);
|
||||
|
||||
private:
|
||||
void WarnNilArg(NodeTy* N, const ObjCMessageExpr* ME, unsigned Arg) {
|
||||
|
@ -103,7 +103,7 @@ clang::CreateBasicObjCFoundationChecks(ASTContext& Ctx, BugReporter& BR) {
|
|||
|
||||
|
||||
|
||||
bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
|
||||
bool BasicObjCFoundationChecks::Audit(ExplodedNode* N,
|
||||
GRStateManager&) {
|
||||
|
||||
const ObjCMessageExpr* ME =
|
||||
|
@ -254,10 +254,10 @@ public:
|
|||
|
||||
~AuditCFNumberCreate() {}
|
||||
|
||||
bool Audit(ExplodedNode<GRState>* N, GRStateManager&);
|
||||
bool Audit(ExplodedNode* N, GRStateManager&);
|
||||
|
||||
private:
|
||||
void AddError(const TypedRegion* R, const Expr* Ex, ExplodedNode<GRState> *N,
|
||||
void AddError(const TypedRegion* R, const Expr* Ex, ExplodedNode *N,
|
||||
uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
@ -355,7 +355,7 @@ static const char* GetCFNumberTypeStr(uint64_t i) {
|
|||
}
|
||||
#endif
|
||||
|
||||
bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
|
||||
bool AuditCFNumberCreate::Audit(ExplodedNode* N,GRStateManager&){
|
||||
const CallExpr* CE =
|
||||
cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
|
||||
const Expr* Callee = CE->getCallee();
|
||||
|
@ -422,7 +422,7 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
|
|||
}
|
||||
|
||||
void AuditCFNumberCreate::AddError(const TypedRegion* R, const Expr* Ex,
|
||||
ExplodedNode<GRState> *N,
|
||||
ExplodedNode *N,
|
||||
uint64_t SourceSize, uint64_t TargetSize,
|
||||
uint64_t NumberKind) {
|
||||
|
||||
|
@ -478,12 +478,12 @@ public:
|
|||
|
||||
~AuditCFRetainRelease() {}
|
||||
|
||||
bool Audit(ExplodedNode<GRState>* N, GRStateManager&);
|
||||
bool Audit(ExplodedNode* N, GRStateManager&);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
bool AuditCFRetainRelease::Audit(ExplodedNode<GRState>* N, GRStateManager&) {
|
||||
bool AuditCFRetainRelease::Audit(ExplodedNode* N, GRStateManager&) {
|
||||
const CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
|
||||
|
||||
// If the CallExpr doesn't have exactly 1 argument just give up checking.
|
||||
|
|
|
@ -49,17 +49,17 @@ static inline const Stmt* GetStmt(ProgramPoint P) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline const ExplodedNode<GRState>*
|
||||
GetPredecessorNode(const ExplodedNode<GRState>* N) {
|
||||
static inline const ExplodedNode*
|
||||
GetPredecessorNode(const ExplodedNode* N) {
|
||||
return N->pred_empty() ? NULL : *(N->pred_begin());
|
||||
}
|
||||
|
||||
static inline const ExplodedNode<GRState>*
|
||||
GetSuccessorNode(const ExplodedNode<GRState>* N) {
|
||||
static inline const ExplodedNode*
|
||||
GetSuccessorNode(const ExplodedNode* N) {
|
||||
return N->succ_empty() ? NULL : *(N->succ_begin());
|
||||
}
|
||||
|
||||
static const Stmt* GetPreviousStmt(const ExplodedNode<GRState>* N) {
|
||||
static const Stmt* GetPreviousStmt(const ExplodedNode* N) {
|
||||
for (N = GetPredecessorNode(N); N; N = GetPredecessorNode(N))
|
||||
if (const Stmt *S = GetStmt(N->getLocation()))
|
||||
return S;
|
||||
|
@ -67,7 +67,7 @@ static const Stmt* GetPreviousStmt(const ExplodedNode<GRState>* N) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const Stmt* GetNextStmt(const ExplodedNode<GRState>* N) {
|
||||
static const Stmt* GetNextStmt(const ExplodedNode* N) {
|
||||
for (N = GetSuccessorNode(N); N; N = GetSuccessorNode(N))
|
||||
if (const Stmt *S = GetStmt(N->getLocation())) {
|
||||
// Check if the statement is '?' or '&&'/'||'. These are "merges",
|
||||
|
@ -96,7 +96,7 @@ static const Stmt* GetNextStmt(const ExplodedNode<GRState>* N) {
|
|||
}
|
||||
|
||||
static inline const Stmt*
|
||||
GetCurrentOrPreviousStmt(const ExplodedNode<GRState>* N) {
|
||||
GetCurrentOrPreviousStmt(const ExplodedNode* N) {
|
||||
if (const Stmt *S = GetStmt(N->getLocation()))
|
||||
return S;
|
||||
|
||||
|
@ -104,7 +104,7 @@ GetCurrentOrPreviousStmt(const ExplodedNode<GRState>* N) {
|
|||
}
|
||||
|
||||
static inline const Stmt*
|
||||
GetCurrentOrNextStmt(const ExplodedNode<GRState>* N) {
|
||||
GetCurrentOrNextStmt(const ExplodedNode* N) {
|
||||
if (const Stmt *S = GetStmt(N->getLocation()))
|
||||
return S;
|
||||
|
||||
|
@ -115,8 +115,8 @@ GetCurrentOrNextStmt(const ExplodedNode<GRState>* N) {
|
|||
// PathDiagnosticBuilder and its associated routines and helper objects.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
typedef llvm::DenseMap<const ExplodedNode<GRState>*,
|
||||
const ExplodedNode<GRState>*> NodeBackMap;
|
||||
typedef llvm::DenseMap<const ExplodedNode*,
|
||||
const ExplodedNode*> NodeBackMap;
|
||||
|
||||
namespace {
|
||||
class VISIBILITY_HIDDEN NodeMapClosure : public BugReport::NodeResolver {
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
NodeMapClosure(NodeBackMap *m) : M(*m) {}
|
||||
~NodeMapClosure() {}
|
||||
|
||||
const ExplodedNode<GRState>* getOriginalNode(const ExplodedNode<GRState>* N) {
|
||||
const ExplodedNode* getOriginalNode(const ExplodedNode* N) {
|
||||
NodeBackMap::iterator I = M.find(N);
|
||||
return I == M.end() ? 0 : I->second;
|
||||
}
|
||||
|
@ -146,10 +146,10 @@ public:
|
|||
addVisitor(R);
|
||||
}
|
||||
|
||||
PathDiagnosticLocation ExecutionContinues(const ExplodedNode<GRState>* N);
|
||||
PathDiagnosticLocation ExecutionContinues(const ExplodedNode* N);
|
||||
|
||||
PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream& os,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
|
||||
ParentMap& getParentMap() {
|
||||
if (PM.get() == 0)
|
||||
|
@ -185,7 +185,7 @@ public:
|
|||
} // end anonymous namespace
|
||||
|
||||
PathDiagnosticLocation
|
||||
PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) {
|
||||
PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode* N) {
|
||||
if (const Stmt *S = GetNextStmt(N))
|
||||
return PathDiagnosticLocation(S, getSourceManager());
|
||||
|
||||
|
@ -194,7 +194,7 @@ PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) {
|
|||
|
||||
PathDiagnosticLocation
|
||||
PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream& os,
|
||||
const ExplodedNode<GRState>* N) {
|
||||
const ExplodedNode* N) {
|
||||
|
||||
// Slow, but probably doesn't matter.
|
||||
if (os.str().empty())
|
||||
|
@ -327,7 +327,7 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static const VarDecl*
|
||||
GetMostRecentVarDeclBinding(const ExplodedNode<GRState>* N,
|
||||
GetMostRecentVarDeclBinding(const ExplodedNode* N,
|
||||
GRStateManager& VMgr, SVal X) {
|
||||
|
||||
for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
|
||||
|
@ -366,14 +366,14 @@ class VISIBILITY_HIDDEN NotableSymbolHandler
|
|||
const GRState* PrevSt;
|
||||
const Stmt* S;
|
||||
GRStateManager& VMgr;
|
||||
const ExplodedNode<GRState>* Pred;
|
||||
const ExplodedNode* Pred;
|
||||
PathDiagnostic& PD;
|
||||
BugReporter& BR;
|
||||
|
||||
public:
|
||||
|
||||
NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s,
|
||||
GRStateManager& vmgr, const ExplodedNode<GRState>* pred,
|
||||
GRStateManager& vmgr, const ExplodedNode* pred,
|
||||
PathDiagnostic& pd, BugReporter& br)
|
||||
: Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
|
||||
|
||||
|
@ -440,12 +440,12 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
static void HandleNotableSymbol(const ExplodedNode<GRState>* N,
|
||||
static void HandleNotableSymbol(const ExplodedNode* N,
|
||||
const Stmt* S,
|
||||
SymbolRef Sym, BugReporter& BR,
|
||||
PathDiagnostic& PD) {
|
||||
|
||||
const ExplodedNode<GRState>* Pred = N->pred_empty() ? 0 : *N->pred_begin();
|
||||
const ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin();
|
||||
const GRState* PrevSt = Pred ? Pred->getState() : 0;
|
||||
|
||||
if (!PrevSt)
|
||||
|
@ -463,13 +463,13 @@ class VISIBILITY_HIDDEN ScanNotableSymbols
|
|||
: public StoreManager::BindingsHandler {
|
||||
|
||||
llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
|
||||
const ExplodedNode<GRState>* N;
|
||||
const ExplodedNode* N;
|
||||
const Stmt* S;
|
||||
GRBugReporter& BR;
|
||||
PathDiagnostic& PD;
|
||||
|
||||
public:
|
||||
ScanNotableSymbols(const ExplodedNode<GRState>* n, const Stmt* s,
|
||||
ScanNotableSymbols(const ExplodedNode* n, const Stmt* s,
|
||||
GRBugReporter& br, PathDiagnostic& pd)
|
||||
: N(n), S(s), BR(br), PD(pd) {}
|
||||
|
||||
|
@ -503,10 +503,10 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM);
|
|||
|
||||
static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
||||
PathDiagnosticBuilder &PDB,
|
||||
const ExplodedNode<GRState> *N) {
|
||||
const ExplodedNode *N) {
|
||||
|
||||
SourceManager& SMgr = PDB.getSourceManager();
|
||||
const ExplodedNode<GRState>* NextNode = N->pred_empty()
|
||||
const ExplodedNode* NextNode = N->pred_empty()
|
||||
? NULL : *(N->pred_begin());
|
||||
while (NextNode) {
|
||||
N = NextNode;
|
||||
|
@ -1113,12 +1113,12 @@ void EdgeBuilder::addContext(const Stmt *S) {
|
|||
|
||||
static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
|
||||
PathDiagnosticBuilder &PDB,
|
||||
const ExplodedNode<GRState> *N) {
|
||||
const ExplodedNode *N) {
|
||||
|
||||
|
||||
EdgeBuilder EB(PD, PDB);
|
||||
|
||||
const ExplodedNode<GRState>* NextNode = N->pred_empty()
|
||||
const ExplodedNode* NextNode = N->pred_empty()
|
||||
? NULL : *(N->pred_begin());
|
||||
while (NextNode) {
|
||||
N = NextNode;
|
||||
|
@ -1221,7 +1221,7 @@ const Stmt* BugReport::getStmt(BugReporter& BR) const {
|
|||
|
||||
PathDiagnosticPiece*
|
||||
BugReport::getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* EndPathNode) {
|
||||
const ExplodedNode* EndPathNode) {
|
||||
|
||||
const Stmt* S = getStmt(BRC.getBugReporter());
|
||||
|
||||
|
@ -1269,8 +1269,8 @@ SourceLocation BugReport::getLocation() const {
|
|||
return FullSourceLoc();
|
||||
}
|
||||
|
||||
PathDiagnosticPiece* BugReport::VisitNode(const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode<GRState>* PrevN,
|
||||
PathDiagnosticPiece* BugReport::VisitNode(const ExplodedNode* N,
|
||||
const ExplodedNode* PrevN,
|
||||
BugReporterContext &BRC) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1333,17 +1333,17 @@ void BugReporter::FlushReports() {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static std::pair<std::pair<ExplodedGraph<GRState>*, NodeBackMap*>,
|
||||
std::pair<ExplodedNode<GRState>*, unsigned> >
|
||||
std::pair<ExplodedNode*, unsigned> >
|
||||
MakeReportGraph(const ExplodedGraph<GRState>* G,
|
||||
const ExplodedNode<GRState>** NStart,
|
||||
const ExplodedNode<GRState>** NEnd) {
|
||||
const ExplodedNode** NStart,
|
||||
const ExplodedNode** NEnd) {
|
||||
|
||||
// Create the trimmed graph. It will contain the shortest paths from the
|
||||
// error nodes to the root. In the new graph we should only have one
|
||||
// error node unless there are two or more error nodes with the same minimum
|
||||
// path length.
|
||||
ExplodedGraph<GRState>* GTrim;
|
||||
InterExplodedGraphMap<GRState>* NMap;
|
||||
InterExplodedGraphMap* NMap;
|
||||
|
||||
llvm::DenseMap<const void*, const void*> InverseMap;
|
||||
llvm::tie(GTrim, NMap) = G->Trim(NStart, NEnd, &InverseMap);
|
||||
|
@ -1351,18 +1351,18 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
// Create owning pointers for GTrim and NMap just to ensure that they are
|
||||
// released when this function exists.
|
||||
llvm::OwningPtr<ExplodedGraph<GRState> > AutoReleaseGTrim(GTrim);
|
||||
llvm::OwningPtr<InterExplodedGraphMap<GRState> > AutoReleaseNMap(NMap);
|
||||
llvm::OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
|
||||
|
||||
// Find the (first) error node in the trimmed graph. We just need to consult
|
||||
// the node map (NMap) which maps from nodes in the original graph to nodes
|
||||
// in the new graph.
|
||||
|
||||
std::queue<const ExplodedNode<GRState>*> WS;
|
||||
typedef llvm::DenseMap<const ExplodedNode<GRState>*,unsigned> IndexMapTy;
|
||||
std::queue<const ExplodedNode*> WS;
|
||||
typedef llvm::DenseMap<const ExplodedNode*,unsigned> IndexMapTy;
|
||||
IndexMapTy IndexMap;
|
||||
|
||||
for (const ExplodedNode<GRState>** I = NStart; I != NEnd; ++I)
|
||||
if (const ExplodedNode<GRState> *N = NMap->getMappedNode(*I)) {
|
||||
for (const ExplodedNode** I = NStart; I != NEnd; ++I)
|
||||
if (const ExplodedNode *N = NMap->getMappedNode(*I)) {
|
||||
unsigned NodeIndex = (I - NStart) / sizeof(*I);
|
||||
WS.push(N);
|
||||
IndexMap[*I] = NodeIndex;
|
||||
|
@ -1382,10 +1382,10 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
llvm::DenseMap<const void*,unsigned> Visited;
|
||||
|
||||
unsigned cnt = 0;
|
||||
const ExplodedNode<GRState>* Root = 0;
|
||||
const ExplodedNode* Root = 0;
|
||||
|
||||
while (!WS.empty()) {
|
||||
const ExplodedNode<GRState>* Node = WS.front();
|
||||
const ExplodedNode* Node = WS.front();
|
||||
WS.pop();
|
||||
|
||||
if (Visited.find(Node) != Visited.end())
|
||||
|
@ -1398,7 +1398,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
break;
|
||||
}
|
||||
|
||||
for (ExplodedNode<GRState>::const_pred_iterator I=Node->pred_begin(),
|
||||
for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
|
||||
E=Node->pred_end(); I!=E; ++I)
|
||||
WS.push(*I);
|
||||
}
|
||||
|
@ -1407,24 +1407,24 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
|
||||
// Now walk from the root down the BFS path, always taking the successor
|
||||
// with the lowest number.
|
||||
ExplodedNode<GRState> *Last = 0, *First = 0;
|
||||
ExplodedNode *Last = 0, *First = 0;
|
||||
NodeBackMap *BM = new NodeBackMap();
|
||||
unsigned NodeIndex = 0;
|
||||
|
||||
for ( const ExplodedNode<GRState> *N = Root ;;) {
|
||||
for ( const ExplodedNode *N = Root ;;) {
|
||||
// Lookup the number associated with the current node.
|
||||
llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
|
||||
assert(I != Visited.end());
|
||||
|
||||
// Create the equivalent node in the new graph with the same state
|
||||
// and location.
|
||||
ExplodedNode<GRState>* NewN =
|
||||
ExplodedNode* NewN =
|
||||
GNew->getNode(N->getLocation(), N->getState());
|
||||
|
||||
// Store the mapping to the original node.
|
||||
llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
|
||||
assert(IMitr != InverseMap.end() && "No mapping to original node.");
|
||||
(*BM)[NewN] = (const ExplodedNode<GRState>*) IMitr->second;
|
||||
(*BM)[NewN] = (const ExplodedNode*) IMitr->second;
|
||||
|
||||
// Link up the new node with the previous node.
|
||||
if (Last)
|
||||
|
@ -1434,7 +1434,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
|
||||
// Are we at the final node?
|
||||
IndexMapTy::iterator IMI =
|
||||
IndexMap.find((const ExplodedNode<GRState>*)(IMitr->second));
|
||||
IndexMap.find((const ExplodedNode*)(IMitr->second));
|
||||
if (IMI != IndexMap.end()) {
|
||||
First = NewN;
|
||||
NodeIndex = IMI->second;
|
||||
|
@ -1443,8 +1443,8 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
|
|||
|
||||
// Find the next successor node. We choose the node that is marked
|
||||
// with the lowest DFS number.
|
||||
ExplodedNode<GRState>::const_succ_iterator SI = N->succ_begin();
|
||||
ExplodedNode<GRState>::const_succ_iterator SE = N->succ_end();
|
||||
ExplodedNode::const_succ_iterator SI = N->succ_begin();
|
||||
ExplodedNode::const_succ_iterator SE = N->succ_end();
|
||||
N = 0;
|
||||
|
||||
for (unsigned MinVal = 0; SI != SE; ++SI) {
|
||||
|
@ -1564,10 +1564,10 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||
BugReportEquivClass& EQ) {
|
||||
|
||||
std::vector<const ExplodedNode<GRState>*> Nodes;
|
||||
std::vector<const ExplodedNode*> Nodes;
|
||||
|
||||
for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
|
||||
const ExplodedNode<GRState>* N = I->getEndNode();
|
||||
const ExplodedNode* N = I->getEndNode();
|
||||
if (N) Nodes.push_back(N);
|
||||
}
|
||||
|
||||
|
@ -1577,7 +1577,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
// Construct a new graph that contains only a single path from the error
|
||||
// node to a root.
|
||||
const std::pair<std::pair<ExplodedGraph<GRState>*, NodeBackMap*>,
|
||||
std::pair<ExplodedNode<GRState>*, unsigned> >&
|
||||
std::pair<ExplodedNode*, unsigned> >&
|
||||
GPair = MakeReportGraph(&getGraph(), &Nodes[0], &Nodes[0] + Nodes.size());
|
||||
|
||||
// Find the BugReport with the original location.
|
||||
|
@ -1590,7 +1590,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
|
||||
llvm::OwningPtr<ExplodedGraph<GRState> > ReportGraph(GPair.first.first);
|
||||
llvm::OwningPtr<NodeBackMap> BackMap(GPair.first.second);
|
||||
const ExplodedNode<GRState> *N = GPair.second.first;
|
||||
const ExplodedNode *N = GPair.second.first;
|
||||
|
||||
// Start building the path diagnostic...
|
||||
PathDiagnosticBuilder PDB(*this, R, BackMap.get(), getPathDiagnosticClient());
|
||||
|
|
|
@ -24,7 +24,7 @@ using namespace clang;
|
|||
// Utility functions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
const Stmt *clang::bugreporter::GetDerefExpr(const ExplodedNode<GRState> *N) {
|
||||
const Stmt *clang::bugreporter::GetDerefExpr(const ExplodedNode *N) {
|
||||
// Pattern match for a few useful cases (do something smarter later):
|
||||
// a[0], p->f, *p
|
||||
const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
|
||||
|
@ -46,7 +46,7 @@ const Stmt *clang::bugreporter::GetDerefExpr(const ExplodedNode<GRState> *N) {
|
|||
}
|
||||
|
||||
const Stmt*
|
||||
clang::bugreporter::GetReceiverExpr(const ExplodedNode<GRState> *N){
|
||||
clang::bugreporter::GetReceiverExpr(const ExplodedNode *N){
|
||||
const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
|
||||
if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S))
|
||||
return ME->getReceiver();
|
||||
|
@ -54,7 +54,7 @@ clang::bugreporter::GetReceiverExpr(const ExplodedNode<GRState> *N){
|
|||
}
|
||||
|
||||
const Stmt*
|
||||
clang::bugreporter::GetDenomExpr(const ExplodedNode<GRState> *N) {
|
||||
clang::bugreporter::GetDenomExpr(const ExplodedNode *N) {
|
||||
const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
|
||||
if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
|
||||
return BE->getRHS();
|
||||
|
@ -62,7 +62,7 @@ clang::bugreporter::GetDenomExpr(const ExplodedNode<GRState> *N) {
|
|||
}
|
||||
|
||||
const Stmt*
|
||||
clang::bugreporter::GetCalleeExpr(const ExplodedNode<GRState> *N) {
|
||||
clang::bugreporter::GetCalleeExpr(const ExplodedNode *N) {
|
||||
const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
|
||||
if (const CallExpr *CE = dyn_cast<CallExpr>(S))
|
||||
return CE->getCallee();
|
||||
|
@ -70,7 +70,7 @@ clang::bugreporter::GetCalleeExpr(const ExplodedNode<GRState> *N) {
|
|||
}
|
||||
|
||||
const Stmt*
|
||||
clang::bugreporter::GetRetValExpr(const ExplodedNode<GRState> *N) {
|
||||
clang::bugreporter::GetRetValExpr(const ExplodedNode *N) {
|
||||
const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
|
||||
if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
|
||||
return RS->getRetValue();
|
||||
|
@ -86,20 +86,20 @@ class VISIBILITY_HIDDEN FindLastStoreBRVisitor : public BugReporterVisitor {
|
|||
const MemRegion *R;
|
||||
SVal V;
|
||||
bool satisfied;
|
||||
const ExplodedNode<GRState> *StoreSite;
|
||||
const ExplodedNode *StoreSite;
|
||||
public:
|
||||
FindLastStoreBRVisitor(SVal v, const MemRegion *r)
|
||||
: R(r), V(v), satisfied(false), StoreSite(0) {}
|
||||
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState> *N,
|
||||
const ExplodedNode<GRState> *PrevN,
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
|
||||
const ExplodedNode *PrevN,
|
||||
BugReporterContext& BRC) {
|
||||
|
||||
if (satisfied)
|
||||
return NULL;
|
||||
|
||||
if (!StoreSite) {
|
||||
const ExplodedNode<GRState> *Node = N, *Last = NULL;
|
||||
const ExplodedNode *Node = N, *Last = NULL;
|
||||
|
||||
for ( ; Node ; Last = Node, Node = Node->getFirstPred()) {
|
||||
|
||||
|
@ -234,8 +234,8 @@ public:
|
|||
TrackConstraintBRVisitor(SVal constraint, bool assumption)
|
||||
: Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
|
||||
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState> *N,
|
||||
const ExplodedNode<GRState> *PrevN,
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
|
||||
const ExplodedNode *PrevN,
|
||||
BugReporterContext& BRC) {
|
||||
if (isSatisfied)
|
||||
return NULL;
|
||||
|
@ -297,7 +297,7 @@ static void registerTrackConstraint(BugReporterContext& BRC, SVal Constraint,
|
|||
|
||||
void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
|
||||
const Stmt *S,
|
||||
const ExplodedNode<GRState>* N) {
|
||||
const ExplodedNode* N) {
|
||||
|
||||
if (!S)
|
||||
return;
|
||||
|
|
|
@ -178,8 +178,8 @@ public:
|
|||
GenericNodeBuilder(GREndPathNodeBuilder<GRState> &enb)
|
||||
: SNB(0), S(0), tag(0), ENB(&enb) {}
|
||||
|
||||
ExplodedNode<GRState> *MakeNode(const GRState *state,
|
||||
ExplodedNode<GRState> *Pred) {
|
||||
ExplodedNode *MakeNode(const GRState *state,
|
||||
ExplodedNode *Pred) {
|
||||
if (SNB)
|
||||
return SNB->generateNode(PostStmt(S, tag), state, Pred);
|
||||
|
||||
|
@ -1853,21 +1853,21 @@ private:
|
|||
const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
|
||||
RefVal::Kind& hasErr);
|
||||
|
||||
void ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
|
||||
void ProcessNonLeakError(ExplodedNodeSet& Dst,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
Expr* NodeExpr, Expr* ErrorExpr,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* St,
|
||||
RefVal::Kind hasErr, SymbolRef Sym);
|
||||
|
||||
const GRState * HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
|
||||
llvm::SmallVectorImpl<SymbolRef> &Leaked);
|
||||
|
||||
ExplodedNode<GRState>* ProcessLeaks(const GRState * state,
|
||||
ExplodedNode* ProcessLeaks(const GRState * state,
|
||||
llvm::SmallVectorImpl<SymbolRef> &Leaked,
|
||||
GenericNodeBuilder &Builder,
|
||||
GRExprEngine &Eng,
|
||||
ExplodedNode<GRState> *Pred = 0);
|
||||
ExplodedNode *Pred = 0);
|
||||
|
||||
public:
|
||||
CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
|
||||
|
@ -1888,40 +1888,40 @@ public:
|
|||
bool isGCEnabled() const { return Summaries.isGCEnabled(); }
|
||||
const LangOptions& getLangOptions() const { return LOpts; }
|
||||
|
||||
const RetainSummary *getSummaryOfNode(const ExplodedNode<GRState> *N) const {
|
||||
const RetainSummary *getSummaryOfNode(const ExplodedNode *N) const {
|
||||
SummaryLogTy::const_iterator I = SummaryLog.find(N);
|
||||
return I == SummaryLog.end() ? 0 : I->second;
|
||||
}
|
||||
|
||||
// Calls.
|
||||
|
||||
void EvalSummary(ExplodedNodeSet<GRState>& Dst,
|
||||
void EvalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
Expr* Ex,
|
||||
Expr* Receiver,
|
||||
const RetainSummary& Summ,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ExplodedNode<GRState>* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
ExplodedNode<GRState>* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
bool EvalObjCMessageExprAux(ExplodedNodeSet<GRState>& Dst,
|
||||
bool EvalObjCMessageExprAux(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
ExplodedNode<GRState>* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
// Stores.
|
||||
virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
|
||||
|
@ -1931,24 +1931,24 @@ public:
|
|||
virtual void EvalEndPath(GRExprEngine& Engine,
|
||||
GREndPathNodeBuilder<GRState>& Builder);
|
||||
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
ExplodedNode* Pred,
|
||||
Stmt* S, const GRState* state,
|
||||
SymbolReaper& SymReaper);
|
||||
|
||||
std::pair<ExplodedNode<GRState>*, const GRState *>
|
||||
std::pair<ExplodedNode*, const GRState *>
|
||||
HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
|
||||
ExplodedNode<GRState>* Pred, GRExprEngine &Eng,
|
||||
ExplodedNode* Pred, GRExprEngine &Eng,
|
||||
SymbolRef Sym, RefVal V, bool &stop);
|
||||
// Return statements.
|
||||
|
||||
virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
|
||||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ReturnStmt* S,
|
||||
ExplodedNode<GRState>* Pred);
|
||||
ExplodedNode* Pred);
|
||||
|
||||
// Assumptions.
|
||||
|
||||
|
@ -2123,11 +2123,11 @@ namespace {
|
|||
const CFRefCount &TF;
|
||||
public:
|
||||
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
||||
ExplodedNode<GRState> *n, SymbolRef sym)
|
||||
ExplodedNode *n, SymbolRef sym)
|
||||
: RangedBugReport(D, D.getDescription(), n), Sym(sym), TF(tf) {}
|
||||
|
||||
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
||||
ExplodedNode<GRState> *n, SymbolRef sym, const char* endText)
|
||||
ExplodedNode *n, SymbolRef sym, const char* endText)
|
||||
: RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}
|
||||
|
||||
virtual ~CFRefReport() {}
|
||||
|
@ -2151,12 +2151,12 @@ namespace {
|
|||
SymbolRef getSymbol() const { return Sym; }
|
||||
|
||||
PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
|
||||
std::pair<const char**,const char**> getExtraDescriptiveText();
|
||||
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode<GRState>* PrevN,
|
||||
PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
|
||||
const ExplodedNode* PrevN,
|
||||
BugReporterContext& BRC);
|
||||
};
|
||||
|
||||
|
@ -2165,11 +2165,11 @@ namespace {
|
|||
const MemRegion* AllocBinding;
|
||||
public:
|
||||
CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
||||
ExplodedNode<GRState> *n, SymbolRef sym,
|
||||
ExplodedNode *n, SymbolRef sym,
|
||||
GRExprEngine& Eng);
|
||||
|
||||
PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
|
||||
SourceLocation getLocation() const { return AllocSite; }
|
||||
};
|
||||
|
@ -2273,8 +2273,8 @@ static inline bool contains(const llvm::SmallVectorImpl<ArgEffect>& V,
|
|||
return false;
|
||||
}
|
||||
|
||||
PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode<GRState>* PrevN,
|
||||
PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
|
||||
const ExplodedNode* PrevN,
|
||||
BugReporterContext& BRC) {
|
||||
|
||||
if (!isa<PostStmt>(N->getLocation()))
|
||||
|
@ -2548,13 +2548,13 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
static std::pair<const ExplodedNode<GRState>*,const MemRegion*>
|
||||
GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode<GRState>* N,
|
||||
static std::pair<const ExplodedNode*,const MemRegion*>
|
||||
GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode* N,
|
||||
SymbolRef Sym) {
|
||||
|
||||
// Find both first node that referred to the tracked symbol and the
|
||||
// memory location that value was store to.
|
||||
const ExplodedNode<GRState>* Last = N;
|
||||
const ExplodedNode* Last = N;
|
||||
const MemRegion* FirstBinding = 0;
|
||||
|
||||
while (N) {
|
||||
|
@ -2577,7 +2577,7 @@ GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode<GRState>* N,
|
|||
|
||||
PathDiagnosticPiece*
|
||||
CFRefReport::getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* EndN) {
|
||||
const ExplodedNode* EndN) {
|
||||
// Tell the BugReporterContext to report cases when the tracked symbol is
|
||||
// assigned to different variables, etc.
|
||||
BRC.addNotableSymbol(Sym);
|
||||
|
@ -2586,7 +2586,7 @@ CFRefReport::getEndPath(BugReporterContext& BRC,
|
|||
|
||||
PathDiagnosticPiece*
|
||||
CFRefLeakReport::getEndPath(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* EndN){
|
||||
const ExplodedNode* EndN){
|
||||
|
||||
// Tell the BugReporterContext to report cases when the tracked symbol is
|
||||
// assigned to different variables, etc.
|
||||
|
@ -2595,7 +2595,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
|
|||
// We are reporting a leak. Walk up the graph to get to the first node where
|
||||
// the symbol appeared, and also get the first VarDecl that tracked object
|
||||
// is stored to.
|
||||
const ExplodedNode<GRState>* AllocNode = 0;
|
||||
const ExplodedNode* AllocNode = 0;
|
||||
const MemRegion* FirstBinding = 0;
|
||||
|
||||
llvm::tie(AllocNode, FirstBinding) =
|
||||
|
@ -2611,7 +2611,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
|
|||
// Compute an actual location for the leak. Sometimes a leak doesn't
|
||||
// occur at an actual statement (e.g., transition between blocks; end
|
||||
// of function) so we need to walk the graph and compute a real location.
|
||||
const ExplodedNode<GRState>* LeakN = EndN;
|
||||
const ExplodedNode* LeakN = EndN;
|
||||
PathDiagnosticLocation L;
|
||||
|
||||
while (LeakN) {
|
||||
|
@ -2674,7 +2674,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
|
|||
}
|
||||
|
||||
CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
||||
ExplodedNode<GRState> *n,
|
||||
ExplodedNode *n,
|
||||
SymbolRef sym, GRExprEngine& Eng)
|
||||
: CFRefReport(D, tf, n, sym)
|
||||
{
|
||||
|
@ -2687,7 +2687,7 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|||
// Note that this is *not* the trimmed graph; we are guaranteed, however,
|
||||
// that all ancestor nodes that represent the allocation site have the
|
||||
// same SourceLocation.
|
||||
const ExplodedNode<GRState>* AllocNode = 0;
|
||||
const ExplodedNode* AllocNode = 0;
|
||||
|
||||
llvm::tie(AllocNode, AllocBinding) = // Set AllocBinding.
|
||||
GetAllocationSite(Eng.getStateManager(), getEndNode(), getSymbol());
|
||||
|
@ -2741,14 +2741,14 @@ static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
|
|||
return RetTy;
|
||||
}
|
||||
|
||||
void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
Expr* Ex,
|
||||
Expr* Receiver,
|
||||
const RetainSummary& Summ,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
// Get the state.
|
||||
const GRState *state = Builder.GetState(Pred);
|
||||
|
@ -2962,11 +2962,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
|
|||
}
|
||||
|
||||
|
||||
void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
const FunctionDecl* FD = L.getAsFunctionDecl();
|
||||
RetainSummary* Summ = !FD ? Summaries.getDefaultSummary()
|
||||
: Summaries.getSummary(const_cast<FunctionDecl*>(FD));
|
||||
|
@ -2976,11 +2976,11 @@ void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
|
|||
CE->arg_begin(), CE->arg_end(), Pred);
|
||||
}
|
||||
|
||||
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ObjCMessageExpr* ME,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
RetainSummary* Summ = 0;
|
||||
|
||||
if (Expr* Receiver = ME->getReceiver()) {
|
||||
|
@ -3096,11 +3096,11 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
|
|||
|
||||
// Return statements.
|
||||
|
||||
void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ReturnStmt* S,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
Expr* RetE = S->getRetValue();
|
||||
if (!RetE)
|
||||
|
@ -3202,7 +3202,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
|
|||
// Generate an error node.
|
||||
static int ReturnOwnLeakTag = 0;
|
||||
state = state->set<RefBindings>(Sym, X);
|
||||
ExplodedNode<GRState> *N =
|
||||
ExplodedNode *N =
|
||||
Builder.generateNode(PostStmt(S, &ReturnOwnLeakTag), state, Pred);
|
||||
if (N) {
|
||||
CFRefReport *report =
|
||||
|
@ -3223,7 +3223,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
|
|||
|
||||
static int ReturnNotOwnedForOwnedTag = 0;
|
||||
state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
|
||||
if (ExplodedNode<GRState> *N =
|
||||
if (ExplodedNode *N =
|
||||
Builder.generateNode(PostStmt(S, &ReturnNotOwnedForOwnedTag),
|
||||
state, Pred)) {
|
||||
CFRefReport *report =
|
||||
|
@ -3403,9 +3403,9 @@ const GRState * CFRefCount::Update(const GRState * state, SymbolRef sym,
|
|||
// Handle dead symbols and end-of-path.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
std::pair<ExplodedNode<GRState>*, const GRState *>
|
||||
std::pair<ExplodedNode*, const GRState *>
|
||||
CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
ExplodedNode* Pred,
|
||||
GRExprEngine &Eng,
|
||||
SymbolRef Sym, RefVal V, bool &stop) {
|
||||
|
||||
|
@ -3437,7 +3437,7 @@ CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd
|
|||
V.setAutoreleaseCount(0);
|
||||
}
|
||||
state = state->set<RefBindings>(Sym, V);
|
||||
ExplodedNode<GRState> *N = Bd.MakeNode(state, Pred);
|
||||
ExplodedNode *N = Bd.MakeNode(state, Pred);
|
||||
stop = (N == 0);
|
||||
return std::make_pair(N, state);
|
||||
}
|
||||
|
@ -3448,7 +3448,7 @@ CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd
|
|||
V = V ^ RefVal::ErrorOverAutorelease;
|
||||
state = state->set<RefBindings>(Sym, V);
|
||||
|
||||
if (ExplodedNode<GRState> *N = Bd.MakeNode(state, Pred)) {
|
||||
if (ExplodedNode *N = Bd.MakeNode(state, Pred)) {
|
||||
N->markAsSink();
|
||||
|
||||
std::string sbuf;
|
||||
|
@ -3469,7 +3469,7 @@ CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd
|
|||
BR->EmitReport(report);
|
||||
}
|
||||
|
||||
return std::make_pair((ExplodedNode<GRState>*)0, state);
|
||||
return std::make_pair((ExplodedNode*)0, state);
|
||||
}
|
||||
|
||||
const GRState *
|
||||
|
@ -3486,18 +3486,18 @@ CFRefCount::HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
|
|||
return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
|
||||
}
|
||||
|
||||
ExplodedNode<GRState>*
|
||||
ExplodedNode*
|
||||
CFRefCount::ProcessLeaks(const GRState * state,
|
||||
llvm::SmallVectorImpl<SymbolRef> &Leaked,
|
||||
GenericNodeBuilder &Builder,
|
||||
GRExprEngine& Eng,
|
||||
ExplodedNode<GRState> *Pred) {
|
||||
ExplodedNode *Pred) {
|
||||
|
||||
if (Leaked.empty())
|
||||
return Pred;
|
||||
|
||||
// Generate an intermediate node representing the leak point.
|
||||
ExplodedNode<GRState> *N = Builder.MakeNode(state, Pred);
|
||||
ExplodedNode *N = Builder.MakeNode(state, Pred);
|
||||
|
||||
if (N) {
|
||||
for (llvm::SmallVectorImpl<SymbolRef>::iterator
|
||||
|
@ -3520,7 +3520,7 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng,
|
|||
const GRState *state = Builder.getState();
|
||||
GenericNodeBuilder Bd(Builder);
|
||||
RefBindings B = state->get<RefBindings>();
|
||||
ExplodedNode<GRState> *Pred = 0;
|
||||
ExplodedNode *Pred = 0;
|
||||
|
||||
for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
|
||||
bool stop = false;
|
||||
|
@ -3541,10 +3541,10 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng,
|
|||
ProcessLeaks(state, Leaked, Bd, Eng, Pred);
|
||||
}
|
||||
|
||||
void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
ExplodedNode* Pred,
|
||||
Stmt* S,
|
||||
const GRState* state,
|
||||
SymbolReaper& SymReaper) {
|
||||
|
@ -3596,10 +3596,10 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
|
|||
Builder.MakeNode(Dst, S, Pred, state);
|
||||
}
|
||||
|
||||
void CFRefCount::ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
|
||||
void CFRefCount::ProcessNonLeakError(ExplodedNodeSet& Dst,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
Expr* NodeExpr, Expr* ErrorExpr,
|
||||
ExplodedNode<GRState>* Pred,
|
||||
Expr* NodeExpr, Expr* ErrorExpr,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* St,
|
||||
RefVal::Kind hasErr, SymbolRef Sym) {
|
||||
Builder.BuildSinks = true;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
|
||||
#include "clang/Analysis/PathSensitive/GRState.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
@ -26,27 +27,34 @@ using namespace clang;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// An out of line virtual method to provide a home for the class vtable.
|
||||
ExplodedNodeImpl::Auditor::~Auditor() {}
|
||||
ExplodedNode::Auditor::~Auditor() {}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static ExplodedNodeImpl::Auditor* NodeAuditor = 0;
|
||||
static ExplodedNode::Auditor* NodeAuditor = 0;
|
||||
#endif
|
||||
|
||||
void ExplodedNodeImpl::SetAuditor(ExplodedNodeImpl::Auditor* A) {
|
||||
void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) {
|
||||
#ifndef NDEBUG
|
||||
NodeAuditor = A;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExplodedNodeImpl.
|
||||
// ExplodedNode.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static inline std::vector<ExplodedNodeImpl*>& getVector(void* P) {
|
||||
return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P);
|
||||
static inline std::vector<ExplodedNode*>& getVector(void* P) {
|
||||
return *reinterpret_cast<std::vector<ExplodedNode*>*>(P);
|
||||
}
|
||||
|
||||
void ExplodedNodeImpl::addPredecessor(ExplodedNodeImpl* V) {
|
||||
void ExplodedNode::Profile(llvm::FoldingSetNodeID& ID,
|
||||
const ProgramPoint& Loc,
|
||||
const GRState* state) {
|
||||
ID.Add(Loc);
|
||||
state->Profile(ID);
|
||||
}
|
||||
|
||||
void ExplodedNode::addPredecessor(ExplodedNode* V) {
|
||||
assert (!V->isSink());
|
||||
Preds.addNode(V);
|
||||
V->Succs.addNode(this);
|
||||
|
@ -55,14 +63,14 @@ void ExplodedNodeImpl::addPredecessor(ExplodedNodeImpl* V) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ExplodedNodeImpl::NodeGroup::addNode(ExplodedNodeImpl* N) {
|
||||
void ExplodedNode::NodeGroup::addNode(ExplodedNode* N) {
|
||||
|
||||
assert ((reinterpret_cast<uintptr_t>(N) & Mask) == 0x0);
|
||||
assert (!getFlag());
|
||||
|
||||
if (getKind() == Size1) {
|
||||
if (ExplodedNodeImpl* NOld = getNode()) {
|
||||
std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
|
||||
if (ExplodedNode* NOld = getNode()) {
|
||||
std::vector<ExplodedNode*>* V = new std::vector<ExplodedNode*>();
|
||||
assert ((reinterpret_cast<uintptr_t>(V) & Mask) == 0x0);
|
||||
V->push_back(NOld);
|
||||
V->push_back(N);
|
||||
|
@ -82,7 +90,7 @@ void ExplodedNodeImpl::NodeGroup::addNode(ExplodedNodeImpl* N) {
|
|||
}
|
||||
|
||||
|
||||
unsigned ExplodedNodeImpl::NodeGroup::size() const {
|
||||
unsigned ExplodedNode::NodeGroup::size() const {
|
||||
if (getFlag())
|
||||
return 0;
|
||||
|
||||
|
@ -92,50 +100,50 @@ unsigned ExplodedNodeImpl::NodeGroup::size() const {
|
|||
return getVector(getPtr()).size();
|
||||
}
|
||||
|
||||
ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::begin() const {
|
||||
ExplodedNode** ExplodedNode::NodeGroup::begin() const {
|
||||
if (getFlag())
|
||||
return NULL;
|
||||
|
||||
if (getKind() == Size1)
|
||||
return (ExplodedNodeImpl**) (getPtr() ? &P : NULL);
|
||||
return (ExplodedNode**) (getPtr() ? &P : NULL);
|
||||
else
|
||||
return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).begin()));
|
||||
return const_cast<ExplodedNode**>(&*(getVector(getPtr()).begin()));
|
||||
}
|
||||
|
||||
ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::end() const {
|
||||
ExplodedNode** ExplodedNode::NodeGroup::end() const {
|
||||
if (getFlag())
|
||||
return NULL;
|
||||
|
||||
if (getKind() == Size1)
|
||||
return (ExplodedNodeImpl**) (getPtr() ? &P+1 : NULL);
|
||||
return (ExplodedNode**) (getPtr() ? &P+1 : NULL);
|
||||
else {
|
||||
// Dereferencing end() is undefined behaviour. The vector is not empty, so
|
||||
// we can dereference the last elem and then add 1 to the result.
|
||||
return const_cast<ExplodedNodeImpl**>(&getVector(getPtr()).back()) + 1;
|
||||
return const_cast<ExplodedNode**>(&getVector(getPtr()).back()) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
ExplodedNodeImpl::NodeGroup::~NodeGroup() {
|
||||
ExplodedNode::NodeGroup::~NodeGroup() {
|
||||
if (getKind() == SizeOther) delete &getVector(getPtr());
|
||||
}
|
||||
|
||||
ExplodedGraphImpl*
|
||||
ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources,
|
||||
const ExplodedNodeImpl* const* EndSources,
|
||||
ExplodedGraphImpl::Trim(const ExplodedNode* const* BeginSources,
|
||||
const ExplodedNode* const* EndSources,
|
||||
InterExplodedGraphMapImpl* M,
|
||||
llvm::DenseMap<const void*, const void*> *InverseMap)
|
||||
const {
|
||||
|
||||
typedef llvm::DenseSet<const ExplodedNodeImpl*> Pass1Ty;
|
||||
typedef llvm::DenseSet<const ExplodedNode*> Pass1Ty;
|
||||
Pass1Ty Pass1;
|
||||
|
||||
typedef llvm::DenseMap<const ExplodedNodeImpl*, ExplodedNodeImpl*> Pass2Ty;
|
||||
typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> Pass2Ty;
|
||||
Pass2Ty& Pass2 = M->M;
|
||||
|
||||
llvm::SmallVector<const ExplodedNodeImpl*, 10> WL1, WL2;
|
||||
llvm::SmallVector<const ExplodedNode*, 10> WL1, WL2;
|
||||
|
||||
// ===- Pass 1 (reverse DFS) -===
|
||||
for (const ExplodedNodeImpl* const* I = BeginSources; I != EndSources; ++I) {
|
||||
for (const ExplodedNode* const* I = BeginSources; I != EndSources; ++I) {
|
||||
assert(*I);
|
||||
WL1.push_back(*I);
|
||||
}
|
||||
|
@ -143,7 +151,7 @@ const {
|
|||
// Process the first worklist until it is empty. Because it is a std::list
|
||||
// it acts like a FIFO queue.
|
||||
while (!WL1.empty()) {
|
||||
const ExplodedNodeImpl *N = WL1.back();
|
||||
const ExplodedNode *N = WL1.back();
|
||||
WL1.pop_back();
|
||||
|
||||
// Have we already visited this node? If so, continue to the next one.
|
||||
|
@ -160,7 +168,7 @@ const {
|
|||
}
|
||||
|
||||
// Visit our predecessors and enqueue them.
|
||||
for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I)
|
||||
for (ExplodedNode** I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I)
|
||||
WL1.push_back(*I);
|
||||
}
|
||||
|
||||
|
@ -173,7 +181,7 @@ const {
|
|||
|
||||
// ===- Pass 2 (forward DFS to construct the new graph) -===
|
||||
while (!WL2.empty()) {
|
||||
const ExplodedNodeImpl* N = WL2.back();
|
||||
const ExplodedNode* N = WL2.back();
|
||||
WL2.pop_back();
|
||||
|
||||
// Skip this node if we have already processed it.
|
||||
|
@ -182,7 +190,7 @@ const {
|
|||
|
||||
// Create the corresponding node in the new graph and record the mapping
|
||||
// from the old node to the new node.
|
||||
ExplodedNodeImpl* NewN = G->getNodeImpl(N->getLocation(), N->State, NULL);
|
||||
ExplodedNode* NewN = G->getNodeImpl(N->getLocation(), N->State, NULL);
|
||||
Pass2[N] = NewN;
|
||||
|
||||
// Also record the reverse mapping from the new node to the old node.
|
||||
|
@ -197,7 +205,7 @@ const {
|
|||
|
||||
// Walk through the predecessors of 'N' and hook up their corresponding
|
||||
// nodes in the new graph (if any) to the freshly created node.
|
||||
for (ExplodedNodeImpl **I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) {
|
||||
for (ExplodedNode **I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) {
|
||||
Pass2Ty::iterator PI = Pass2.find(*I);
|
||||
if (PI == Pass2.end())
|
||||
continue;
|
||||
|
@ -209,7 +217,7 @@ const {
|
|||
// been created, we should hook them up as successors. Otherwise, enqueue
|
||||
// the new nodes from the original graph that should have nodes created
|
||||
// in the new graph.
|
||||
for (ExplodedNodeImpl **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) {
|
||||
for (ExplodedNode **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) {
|
||||
Pass2Ty::iterator PI = Pass2.find(*I);
|
||||
if (PI != Pass2.end()) {
|
||||
PI->second->addPredecessor(NewN);
|
||||
|
@ -229,9 +237,9 @@ const {
|
|||
return G;
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
InterExplodedGraphMapImpl::getMappedImplNode(const ExplodedNodeImpl* N) const {
|
||||
llvm::DenseMap<const ExplodedNodeImpl*, ExplodedNodeImpl*>::iterator I =
|
||||
ExplodedNode*
|
||||
InterExplodedGraphMapImpl::getMappedImplNode(const ExplodedNode* N) const {
|
||||
llvm::DenseMap<const ExplodedNode*, ExplodedNode*>::iterator I =
|
||||
M.find(N);
|
||||
|
||||
return I == M.end() ? 0 : I->second;
|
||||
|
|
|
@ -155,7 +155,7 @@ bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
|
|||
WList->setBlockCounter(WU.getBlockCounter());
|
||||
|
||||
// Retrieve the node.
|
||||
ExplodedNodeImpl* Node = WU.getNode();
|
||||
ExplodedNode* Node = WU.getNode();
|
||||
|
||||
// Dispatch on the location type.
|
||||
switch (Node->getLocation().getKind()) {
|
||||
|
@ -183,7 +183,7 @@ bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
|
|||
}
|
||||
|
||||
void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L,
|
||||
ExplodedNodeImpl* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
CFGBlock* Blk = L.getDst();
|
||||
|
||||
|
@ -208,7 +208,7 @@ void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L,
|
|||
}
|
||||
|
||||
void GRCoreEngineImpl::HandleBlockEntrance(const BlockEntrance& L,
|
||||
ExplodedNodeImpl* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
// Increment the block counter.
|
||||
GRBlockCounter Counter = WList->getBlockCounter();
|
||||
|
@ -228,7 +228,7 @@ GRCoreEngineImpl::~GRCoreEngineImpl() {
|
|||
delete WList;
|
||||
}
|
||||
|
||||
void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
|
||||
void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
|
||||
|
||||
if (Stmt* Term = B->getTerminator()) {
|
||||
switch (Term->getStmtClass()) {
|
||||
|
@ -317,7 +317,7 @@ void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
|
|||
}
|
||||
|
||||
void GRCoreEngineImpl::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
|
||||
ExplodedNodeImpl* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
assert (B->succ_size() == 2);
|
||||
|
||||
GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
|
||||
|
@ -327,7 +327,7 @@ void GRCoreEngineImpl::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
|
|||
}
|
||||
|
||||
void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
|
||||
unsigned StmtIdx, ExplodedNodeImpl* Pred) {
|
||||
unsigned StmtIdx, ExplodedNode* Pred) {
|
||||
|
||||
assert (!B->empty());
|
||||
|
||||
|
@ -342,10 +342,10 @@ void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
|
|||
/// GenerateNode - Utility method to generate nodes, hook up successors,
|
||||
/// and add nodes to the worklist.
|
||||
void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State,
|
||||
ExplodedNodeImpl* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
bool IsNew;
|
||||
ExplodedNodeImpl* Node = G->getNodeImpl(Loc, State, &IsNew);
|
||||
ExplodedNode* Node = G->getNodeImpl(Loc, State, &IsNew);
|
||||
|
||||
if (Pred)
|
||||
Node->addPredecessor(Pred); // Link 'Node' with its predecessor.
|
||||
|
@ -359,7 +359,7 @@ void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State,
|
|||
}
|
||||
|
||||
GRStmtNodeBuilderImpl::GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
|
||||
ExplodedNodeImpl* N, GRCoreEngineImpl* e)
|
||||
ExplodedNode* N, GRCoreEngineImpl* e)
|
||||
: Eng(*e), B(*b), Idx(idx), Pred(N), LastNode(N) {
|
||||
Deferred.insert(N);
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ GRStmtNodeBuilderImpl::~GRStmtNodeBuilderImpl() {
|
|||
GenerateAutoTransition(*I);
|
||||
}
|
||||
|
||||
void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNodeImpl* N) {
|
||||
void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNode* N) {
|
||||
assert (!N->isSink());
|
||||
|
||||
PostStmt Loc(getStmt());
|
||||
|
@ -383,7 +383,7 @@ void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNodeImpl* N) {
|
|||
}
|
||||
|
||||
bool IsNew;
|
||||
ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(Loc, N->State, &IsNew);
|
||||
ExplodedNode* Succ = Eng.G->getNodeImpl(Loc, N->State, &IsNew);
|
||||
Succ->addPredecessor(N);
|
||||
|
||||
if (IsNew)
|
||||
|
@ -425,9 +425,9 @@ static inline PostStmt GetPostLoc(const Stmt* S, ProgramPoint::Kind K,
|
|||
}
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State,
|
||||
ExplodedNodeImpl* Pred,
|
||||
ExplodedNode* Pred,
|
||||
ProgramPoint::Kind K,
|
||||
const void *tag) {
|
||||
return K == ProgramPoint::PreStmtKind
|
||||
|
@ -435,12 +435,12 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State,
|
|||
: generateNodeImpl(GetPostLoc(S, K, tag), State, Pred);
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc,
|
||||
const void* State,
|
||||
ExplodedNodeImpl* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
bool IsNew;
|
||||
ExplodedNodeImpl* N = Eng.G->getNodeImpl(Loc, State, &IsNew);
|
||||
ExplodedNode* N = Eng.G->getNodeImpl(Loc, State, &IsNew);
|
||||
N->addPredecessor(Pred);
|
||||
Deferred.erase(Pred);
|
||||
|
||||
|
@ -454,7 +454,7 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
|
||||
ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
|
||||
bool branch) {
|
||||
|
||||
// If the branch has been marked infeasible we should not generate a node.
|
||||
|
@ -463,7 +463,7 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
|
|||
|
||||
bool IsNew;
|
||||
|
||||
ExplodedNodeImpl* Succ =
|
||||
ExplodedNode* Succ =
|
||||
Eng.G->getNodeImpl(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew);
|
||||
|
||||
Succ->addPredecessor(Pred);
|
||||
|
@ -490,13 +490,13 @@ GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
|
|||
}
|
||||
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
|
||||
const void* St,
|
||||
bool isSink) {
|
||||
bool IsNew;
|
||||
|
||||
ExplodedNodeImpl* Succ =
|
||||
ExplodedNode* Succ =
|
||||
Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()), St, &IsNew);
|
||||
|
||||
Succ->addPredecessor(Pred);
|
||||
|
@ -515,13 +515,13 @@ GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
|
|||
}
|
||||
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
|
||||
const void* St) {
|
||||
|
||||
bool IsNew;
|
||||
|
||||
ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()),
|
||||
ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()),
|
||||
St, &IsNew);
|
||||
Succ->addPredecessor(Pred);
|
||||
|
||||
|
@ -534,7 +534,7 @@ GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
|
|||
}
|
||||
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
|
||||
bool isSink) {
|
||||
|
||||
|
@ -544,7 +544,7 @@ GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
|
|||
|
||||
bool IsNew;
|
||||
|
||||
ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
|
||||
ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
|
||||
St, &IsNew);
|
||||
Succ->addPredecessor(Pred);
|
||||
|
||||
|
@ -565,14 +565,14 @@ GREndPathNodeBuilderImpl::~GREndPathNodeBuilderImpl() {
|
|||
if (!HasGeneratedNode) generateNodeImpl(Pred->State);
|
||||
}
|
||||
|
||||
ExplodedNodeImpl*
|
||||
ExplodedNode*
|
||||
GREndPathNodeBuilderImpl::generateNodeImpl(const void* State,
|
||||
const void *tag,
|
||||
ExplodedNodeImpl* P) {
|
||||
ExplodedNode* P) {
|
||||
HasGeneratedNode = true;
|
||||
bool IsNew;
|
||||
|
||||
ExplodedNodeImpl* Node =
|
||||
ExplodedNode* Node =
|
||||
Eng.G->getNodeImpl(BlockEntrance(&B, tag), State, &IsNew);
|
||||
|
||||
Node->addPredecessor(P ? P : Pred);
|
||||
|
|
|
@ -1298,11 +1298,11 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
|
|||
// http://developer.apple.com/documentation/Darwin/Reference/Manpages/man3
|
||||
// atomic.3.html
|
||||
//
|
||||
static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
|
||||
static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
|
||||
// Not enough arguments to match OSAtomicCompareAndSwap?
|
||||
if (CE->getNumArgs() != 3)
|
||||
|
@ -1342,14 +1342,14 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
|
|||
|
||||
// Load 'theValue'.
|
||||
const GRState *state = Pred->getState();
|
||||
ExplodedNodeSet<GRState> Tmp;
|
||||
ExplodedNodeSet Tmp;
|
||||
SVal location = state->getSVal(theValueExpr);
|
||||
Engine.EvalLoad(Tmp, theValueExpr, Pred, state, location, OSAtomicLoadTag);
|
||||
|
||||
for (ExplodedNodeSet<GRState>::iterator I = Tmp.begin(), E = Tmp.end();
|
||||
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end();
|
||||
I != E; ++I) {
|
||||
|
||||
ExplodedNode<GRState> *N = *I;
|
||||
ExplodedNode *N = *I;
|
||||
const GRState *stateLoad = N->getState();
|
||||
SVal theValueVal = stateLoad->getSVal(theValueExpr);
|
||||
SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
|
||||
|
@ -1368,7 +1368,7 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
|
|||
// Were they equal?
|
||||
if (stateEqual) {
|
||||
// Perform the store.
|
||||
ExplodedNodeSet<GRState> TmpStore;
|
||||
ExplodedNodeSet TmpStore;
|
||||
SVal val = stateEqual->getSVal(newValueExpr);
|
||||
|
||||
// Handle implicit value casts.
|
||||
|
@ -1383,9 +1383,9 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
|
|||
val, OSAtomicStoreTag);
|
||||
|
||||
// Now bind the result of the comparison.
|
||||
for (ExplodedNodeSet<GRState>::iterator I2 = TmpStore.begin(),
|
||||
for (ExplodedNodeSet::iterator I2 = TmpStore.begin(),
|
||||
E2 = TmpStore.end(); I2 != E2; ++I2) {
|
||||
ExplodedNode<GRState> *predNew = *I2;
|
||||
ExplodedNode *predNew = *I2;
|
||||
const GRState *stateNew = predNew->getState();
|
||||
SVal Res = Engine.getValueManager().makeTruthVal(true, CE->getType());
|
||||
Engine.MakeNode(Dst, CE, predNew, stateNew->bindExpr(CE, Res));
|
||||
|
@ -1402,11 +1402,11 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool EvalOSAtomic(ExplodedNodeSet<GRState>& Dst,
|
||||
static bool EvalOSAtomic(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
ExplodedNode* Pred) {
|
||||
const FunctionDecl* FD = L.getAsFunctionDecl();
|
||||
if (!FD)
|
||||
return false;
|
||||
|
|
|
@ -28,12 +28,12 @@ using namespace clang::bugreporter;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <typename ITERATOR> inline
|
||||
ExplodedNode<GRState>* GetNode(ITERATOR I) {
|
||||
ExplodedNode* GetNode(ITERATOR I) {
|
||||
return *I;
|
||||
}
|
||||
|
||||
template <> inline
|
||||
ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
|
||||
ExplodedNode* GetNode(GRExprEngine::undef_arg_iterator I) {
|
||||
return I->first;
|
||||
}
|
||||
|
||||
|
@ -46,15 +46,15 @@ namespace {
|
|||
class VISIBILITY_HIDDEN BuiltinBugReport : public RangedBugReport {
|
||||
public:
|
||||
BuiltinBugReport(BugType& bt, const char* desc,
|
||||
ExplodedNode<GRState> *n)
|
||||
ExplodedNode *n)
|
||||
: RangedBugReport(bt, desc, n) {}
|
||||
|
||||
BuiltinBugReport(BugType& bt, const char *shortDesc, const char *desc,
|
||||
ExplodedNode<GRState> *n)
|
||||
ExplodedNode *n)
|
||||
: RangedBugReport(bt, shortDesc, desc, n) {}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N);
|
||||
const ExplodedNode* N);
|
||||
};
|
||||
|
||||
class VISIBILITY_HIDDEN BuiltinBug : public BugType {
|
||||
|
@ -73,7 +73,7 @@ public:
|
|||
void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, Eng); }
|
||||
|
||||
virtual void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {}
|
||||
|
||||
template <typename ITER> void Emit(BugReporter& BR, ITER I, ITER E);
|
||||
|
@ -87,7 +87,7 @@ void BuiltinBug::Emit(BugReporter& BR, ITER I, ITER E) {
|
|||
}
|
||||
|
||||
void BuiltinBugReport::registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N) {
|
||||
const ExplodedNode* N) {
|
||||
static_cast<BuiltinBug&>(getBugType()).registerInitialVisitors(BRC, N, this);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ public:
|
|||
}
|
||||
}
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetDenomExpr(N), N);
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetCalleeExpr(N), N);
|
||||
}
|
||||
|
@ -237,12 +237,12 @@ public:
|
|||
class VISIBILITY_HIDDEN ArgReport : public BuiltinBugReport {
|
||||
const Stmt *Arg;
|
||||
public:
|
||||
ArgReport(BugType& bt, const char* desc, ExplodedNode<GRState> *n,
|
||||
ArgReport(BugType& bt, const char* desc, ExplodedNode *n,
|
||||
const Stmt *arg)
|
||||
: BuiltinBugReport(bt, desc, n), Arg(arg) {}
|
||||
|
||||
ArgReport(BugType& bt, const char *shortDesc, const char *desc,
|
||||
ExplodedNode<GRState> *n, const Stmt *arg)
|
||||
ExplodedNode *n, const Stmt *arg)
|
||||
: BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {}
|
||||
|
||||
const Stmt *getArg() const { return Arg; }
|
||||
|
@ -268,7 +268,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
|
||||
N);
|
||||
|
@ -304,7 +304,7 @@ public:
|
|||
|
||||
// Generate a report for this bug.
|
||||
BuiltinBugReport *report = new BuiltinBugReport(*this, desc.c_str(), *I);
|
||||
ExplodedNode<GRState>* N = *I;
|
||||
ExplodedNode* N = *I;
|
||||
const Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
|
||||
const Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
|
||||
assert (E && "Receiver cannot be NULL");
|
||||
|
@ -314,7 +314,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ public:
|
|||
for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
|
||||
End = Eng.ret_stackaddr_end(); I!=End; ++I) {
|
||||
|
||||
ExplodedNode<GRState>* N = *I;
|
||||
ExplodedNode* N = *I;
|
||||
const Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
|
||||
const Expr* E = cast<ReturnStmt>(S)->getRetValue();
|
||||
assert(E && "Return expression cannot be NULL");
|
||||
|
@ -387,7 +387,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, GetRetValExpr(N), N);
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ public:
|
|||
// Note: any predecessor will do. They should have identical state,
|
||||
// since all the BlockEdge did was act as an error sink since the value
|
||||
// had to already be undefined.
|
||||
ExplodedNode<GRState> *N = *(*I)->pred_begin();
|
||||
ExplodedNode *N = *(*I)->pred_begin();
|
||||
ProgramPoint P = N->getLocation();
|
||||
const GRState* St = (*I)->getState();
|
||||
|
||||
|
@ -461,7 +461,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
|
||||
N);
|
||||
|
@ -527,7 +527,7 @@ public:
|
|||
}
|
||||
|
||||
void registerInitialVisitors(BugReporterContext& BRC,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const ExplodedNode* N,
|
||||
BuiltinBugReport *R) {
|
||||
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
|
||||
N);
|
||||
|
@ -583,7 +583,7 @@ public:
|
|||
if (stateNull && !stateNotNull) {
|
||||
// Generate an error node. Check for a null node in case
|
||||
// we cache out.
|
||||
if (ExplodedNode<GRState> *errorNode = C.generateNode(CE, stateNull)) {
|
||||
if (ExplodedNode *errorNode = C.generateNode(CE, stateNull)) {
|
||||
|
||||
// Lazily allocate the BugType object if it hasn't already been
|
||||
// created. Ownership is transferred to the BugReporter object once
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
using namespace clang;
|
||||
|
||||
static ExplodedNodeImpl::Auditor* CreateUbiViz();
|
||||
static ExplodedNode::Auditor* CreateUbiViz();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Basic type definitions.
|
||||
|
@ -308,10 +308,10 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf,
|
|||
}
|
||||
|
||||
// Set the graph auditor.
|
||||
llvm::OwningPtr<ExplodedNodeImpl::Auditor> Auditor;
|
||||
llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
|
||||
if (mgr.shouldVisualizeUbigraph()) {
|
||||
Auditor.reset(CreateUbiViz());
|
||||
ExplodedNodeImpl::SetAuditor(Auditor.get());
|
||||
ExplodedNode::SetAuditor(Auditor.get());
|
||||
}
|
||||
|
||||
// Execute the worklist algorithm.
|
||||
|
@ -319,7 +319,7 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf,
|
|||
|
||||
// Release the auditor (if any) so that it doesn't monitor the graph
|
||||
// created BugReporter.
|
||||
ExplodedNodeImpl::SetAuditor(0);
|
||||
ExplodedNode::SetAuditor(0);
|
||||
|
||||
// Visualize the exploded graph.
|
||||
if (mgr.shouldVisualizeGraphviz())
|
||||
|
@ -443,7 +443,7 @@ ASTConsumer* clang::CreateAnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
|
|||
|
||||
namespace {
|
||||
|
||||
class UbigraphViz : public ExplodedNodeImpl::Auditor {
|
||||
class UbigraphViz : public ExplodedNode::Auditor {
|
||||
llvm::OwningPtr<llvm::raw_ostream> Out;
|
||||
llvm::sys::Path Dir, Filename;
|
||||
unsigned Cntr;
|
||||
|
@ -457,12 +457,12 @@ public:
|
|||
|
||||
~UbigraphViz();
|
||||
|
||||
virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst);
|
||||
virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
static ExplodedNodeImpl::Auditor* CreateUbiViz() {
|
||||
static ExplodedNode::Auditor* CreateUbiViz() {
|
||||
std::string ErrMsg;
|
||||
|
||||
llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
|
||||
|
@ -489,7 +489,7 @@ static ExplodedNodeImpl::Auditor* CreateUbiViz() {
|
|||
return new UbigraphViz(Stream.take(), Dir, Filename);
|
||||
}
|
||||
|
||||
void UbigraphViz::AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) {
|
||||
void UbigraphViz::AddEdge(ExplodedNode* Src, ExplodedNode* Dst) {
|
||||
|
||||
assert (Src != Dst && "Self-edges are not allowed.");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче