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; }
BugType& BT;
std::string ShortDescription;
std::string Description;
- const ExplodedNode<GRState> *EndNode;
+ const ExplodedNode *EndNode;
SourceRange R;
protected:
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();
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.
// 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
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) {}
};
//===----------------------------------------------------------------------===//
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();
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
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),
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);
}
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);
namespace clang {
+class GRState;
class GRCoreEngineImpl;
-class ExplodedNodeImpl;
+class ExplodedNode;
class CFG;
class ASTContext;
// on top of these classes.
//===----------------------------------------------------------------------===//
-class ExplodedNodeImpl : public llvm::FoldingSetNode {
+class ExplodedNode : public llvm::FoldingSetNode {
protected:
friend class ExplodedGraphImpl;
friend class GRCoreEngineImpl;
return reinterpret_cast<void*>(P & ~Mask);
}
- ExplodedNodeImpl* getNode() const {
- return reinterpret_cast<ExplodedNodeImpl*>(getPtr());
+ ExplodedNode *getNode() const {
+ return reinterpret_cast<ExplodedNode*>(getPtr());
}
public:
~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);
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(); }
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());
}
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();
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();
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;
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
/// 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;
}
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:
// 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));
}
};
class ExplodedGraph : public ExplodedGraphImpl {
public:
typedef STATE StateTy;
- typedef ExplodedNode<StateTy> NodeTy;
+ typedef ExplodedNode NodeTy;
typedef llvm::FoldingSet<NodeTy> AllNodesTy;
protected:
- /// Nodes - The nodes in the graph.
- AllNodesTy Nodes;
-
-protected:
- virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
- const void* State,
- bool* IsNew) {
+ 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 ExplodedGraphImpl* MakeEmptyGraph() const {
return new ExplodedGraph(cfg, CodeDecl, Ctx);
}
/// 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.
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);
}
};
-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) {
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(); }
// 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) {
}
};
- 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) {
template <typename STATE>
class GRAuditor {
public:
- typedef ExplodedNode<STATE> NodeTy;
+ typedef ExplodedNode NodeTy;
typedef typename STATE::ManagerTy ManagerTy;
virtual ~GRAuditor() {}
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
/// 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;
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;
}
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);
}
public:
typedef STATE StateTy;
typedef typename StateTy::ManagerTy StateManagerTy;
- typedef ExplodedNode<StateTy> NodeTy;
+ typedef ExplodedNode NodeTy;
private:
GRStmtNodeBuilderImpl& NB;
}
const StateTy* GetState(NodeTy* Pred) const {
- if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
+ if ((ExplodedNode*) Pred == NB.getBasePredecessor())
return CleanedState;
else
return Pred->getState();
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);
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;
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;
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;
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) {}
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; }
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) {}
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; }
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();}
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; }
};
template<typename STATE>
class GREndPathNodeBuilder {
typedef STATE StateTy;
- typedef ExplodedNode<StateTy> NodeTy;
+ typedef ExplodedNode NodeTy;
GREndPathNodeBuilderImpl& NB;
typedef GRIndirectGotoNodeBuilder<StateTy> IndirectGotoNodeBuilder;
typedef GRSwitchNodeBuilder<StateTy> SwitchNodeBuilder;
typedef GREndPathNodeBuilder<StateTy> EndPathNodeBuilder;
- typedef ExplodedNodeSet<StateTy> NodeSet;
+ typedef ExplodedNodeSet NodeSet;
protected:
GRCoreEngine<GRExprEngine> CoreEngine;
// 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.
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,
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; }
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));
}
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) {
-bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
+bool BasicObjCFoundationChecks::Audit(ExplodedNode* N,
GRStateManager&) {
const ObjCMessageExpr* ME =
~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
}
#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();
}
void AuditCFNumberCreate::AddError(const TypedRegion* R, const Expr* Ex,
- ExplodedNode<GRState> *N,
+ ExplodedNode *N,
uint64_t SourceSize, uint64_t TargetSize,
uint64_t NumberKind) {
~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.
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;
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",
}
static inline const Stmt*
-GetCurrentOrPreviousStmt(const ExplodedNode<GRState>* N) {
+GetCurrentOrPreviousStmt(const ExplodedNode* N) {
if (const Stmt *S = GetStmt(N->getLocation()))
return S;
}
static inline const Stmt*
-GetCurrentOrNextStmt(const ExplodedNode<GRState>* N) {
+GetCurrentOrNextStmt(const ExplodedNode* N) {
if (const Stmt *S = GetStmt(N->getLocation()))
return S;
// 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 {
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;
}
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)
} // 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());
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())
//===----------------------------------------------------------------------===//
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()) {
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) {}
};
}
-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)
: 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) {}
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;
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;
PathDiagnosticPiece*
BugReport::getEndPath(BugReporterContext& BRC,
- const ExplodedNode<GRState>* EndPathNode) {
+ const ExplodedNode* EndPathNode) {
const Stmt* S = getStmt(BRC.getBugReporter());
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;
}
//===----------------------------------------------------------------------===//
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);
// 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;
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())
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);
}
// 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)
// 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;
// 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) {
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);
}
// 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.
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());
// 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();
}
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();
}
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();
}
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();
}
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();
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()) {
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;
void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
const Stmt *S,
- const ExplodedNode<GRState>* N) {
+ const ExplodedNode* N) {
if (!S)
return;
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);
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)
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);
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.
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() {}
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);
};
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; }
};
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()))
};
}
-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) {
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);
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.
// 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) =
// 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) {
}
CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
- ExplodedNode<GRState> *n,
+ ExplodedNode *n,
SymbolRef sym, GRExprEngine& Eng)
: CFRefReport(D, tf, n, sym)
{
// 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());
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);
}
-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));
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()) {
// 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)
// 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 =
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 =
// 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) {
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);
}
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;
BR->EmitReport(report);
}
- return std::make_pair((ExplodedNode<GRState>*)0, state);
+ return std::make_pair((ExplodedNode*)0, state);
}
const GRState *
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
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;
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) {
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;
//===----------------------------------------------------------------------===//
#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"
//===----------------------------------------------------------------------===//
// 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);
#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);
}
-unsigned ExplodedNodeImpl::NodeGroup::size() const {
+unsigned ExplodedNode::NodeGroup::size() const {
if (getFlag())
return 0;
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);
}
// 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.
}
// 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);
}
// ===- 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.
// 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.
// 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;
// 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);
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;
WList->setBlockCounter(WU.getBlockCounter());
// Retrieve the node.
- ExplodedNodeImpl* Node = WU.getNode();
+ ExplodedNode* Node = WU.getNode();
// Dispatch on the location type.
switch (Node->getLocation().getKind()) {
}
void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L,
- ExplodedNodeImpl* Pred) {
+ ExplodedNode* Pred) {
CFGBlock* Blk = L.getDst();
}
void GRCoreEngineImpl::HandleBlockEntrance(const BlockEntrance& L,
- ExplodedNodeImpl* Pred) {
+ ExplodedNode* Pred) {
// Increment the block counter.
GRBlockCounter Counter = WList->getBlockCounter();
delete WList;
}
-void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
+void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
if (Stmt* Term = B->getTerminator()) {
switch (Term->getStmtClass()) {
}
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),
}
void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
- unsigned StmtIdx, ExplodedNodeImpl* Pred) {
+ unsigned StmtIdx, ExplodedNode* Pred) {
assert (!B->empty());
/// 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.
}
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);
}
GenerateAutoTransition(*I);
}
-void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNodeImpl* N) {
+void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNode* N) {
assert (!N->isSink());
PostStmt Loc(getStmt());
}
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)
}
}
-ExplodedNodeImpl*
+ExplodedNode*
GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State,
- ExplodedNodeImpl* Pred,
+ ExplodedNode* Pred,
ProgramPoint::Kind K,
const void *tag) {
return K == ProgramPoint::PreStmtKind
: 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);
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.
bool IsNew;
- ExplodedNodeImpl* Succ =
+ ExplodedNode* Succ =
Eng.G->getNodeImpl(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew);
Succ->addPredecessor(Pred);
}
-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);
}
-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);
}
-ExplodedNodeImpl*
+ExplodedNode*
GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
bool isSink) {
bool IsNew;
- ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
+ ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
St, &IsNew);
Succ->addPredecessor(Pred);
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);
// 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)
// 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);
// Were they equal?
if (stateEqual) {
// Perform the store.
- ExplodedNodeSet<GRState> TmpStore;
+ ExplodedNodeSet TmpStore;
SVal val = stateEqual->getSVal(newValueExpr);
// Handle implicit value casts.
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));
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;
//===----------------------------------------------------------------------===//
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;
}
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 {
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);
}
void BuiltinBugReport::registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N) {
+ const ExplodedNode* N) {
static_cast<BuiltinBug&>(getBugType()).registerInitialVisitors(BRC, N, this);
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
}
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetDenomExpr(N), N);
}
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetCalleeExpr(N), N);
}
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; }
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
N);
// 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");
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
}
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");
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, GetRetValExpr(N), N);
}
// 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();
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
N);
}
void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode<GRState>* N,
+ const ExplodedNode* N,
BuiltinBugReport *R) {
registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
N);
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
using namespace clang;
-static ExplodedNodeImpl::Auditor* CreateUbiViz();
+static ExplodedNode::Auditor* CreateUbiViz();
//===----------------------------------------------------------------------===//
// Basic type definitions.
}
// 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.
// 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())
namespace {
-class UbigraphViz : public ExplodedNodeImpl::Auditor {
+class UbigraphViz : public ExplodedNode::Auditor {
llvm::OwningPtr<llvm::raw_ostream> Out;
llvm::sys::Path Dir, Filename;
unsigned Cntr;
~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);
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.");