Simplify GRIndirectGotoNodeBuilder.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47068 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-02-13 17:27:37 +00:00
Родитель a58e833c81
Коммит 24f1a96774
3 изменённых файлов: 30 добавлений и 48 удалений

Просмотреть файл

@ -449,10 +449,8 @@ void GRConstants::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
LabelStmt* L = cast<lval::GotoLabel>(V).getLabel(); LabelStmt* L = cast<lval::GotoLabel>(V).getLabel();
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) { for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
IndirectGotoNodeBuilder::Destination D = *I; if (I.getLabel() == L) {
builder.generateNode(I, St);
if (D.getLabel() == L) {
builder.generateNode(D, St);
return; return;
} }
} }
@ -463,7 +461,7 @@ void GRConstants::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
if (isa<lval::ConcreteInt>(V) || isa<UninitializedVal>(V)) { if (isa<lval::ConcreteInt>(V) || isa<UninitializedVal>(V)) {
// Dispatch to the first target and mark it as a sink. // Dispatch to the first target and mark it as a sink.
NodeTy* N = builder.generateNode(*builder.begin(), St, true); NodeTy* N = builder.generateNode(builder.begin(), St, true);
UninitBranches.insert(N); UninitBranches.insert(N);
return; return;
} }
@ -473,7 +471,7 @@ void GRConstants::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
assert (isa<UnknownVal>(V)); assert (isa<UnknownVal>(V));
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
builder.generateNode(*I, St); builder.generateNode(I, St);
} }
void GRConstants::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, void GRConstants::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,

Просмотреть файл

@ -361,32 +361,15 @@ GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
if (!(*I)->isSink()) Eng.WList->Enqueue(*I); if (!(*I)->isSink()) Eng.WList->Enqueue(*I);
} }
GRIndirectGotoNodeBuilderImpl::Destination
GRIndirectGotoNodeBuilderImpl::Iterator::operator*() {
CFGBlock* B = *I;
assert (!B->empty());
LabelStmt* L = cast<LabelStmt>(B->getLabel());
return Destination(L, *I);
}
GRIndirectGotoNodeBuilderImpl::Iterator
GRIndirectGotoNodeBuilderImpl::begin() {
return Iterator(DispatchBlock.succ_begin());
}
GRIndirectGotoNodeBuilderImpl::Iterator
GRIndirectGotoNodeBuilderImpl::end() {
return Iterator(DispatchBlock.succ_end());
}
ExplodedNodeImpl* ExplodedNodeImpl*
GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Destination& D, GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
void* St, void* St,
bool isSink) { bool isSink) {
bool IsNew; bool IsNew;
ExplodedNodeImpl* Succ = ExplodedNodeImpl* Succ =
Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, D.getBlock(), true), Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, I.getBlock(), true),
St, &IsNew); St, &IsNew);
Succ->addPredecessor(Pred); Succ->addPredecessor(Pred);

Просмотреть файл

@ -15,11 +15,13 @@
#ifndef LLVM_CLANG_ANALYSIS_GRENGINE #ifndef LLVM_CLANG_ANALYSIS_GRENGINE
#define LLVM_CLANG_ANALYSIS_GRENGINE #define LLVM_CLANG_ANALYSIS_GRENGINE
#include "clang/AST/Stmt.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h" #include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "clang/Analysis/PathSensitive/GRWorkList.h" #include "clang/Analysis/PathSensitive/GRWorkList.h"
#include "clang/Analysis/PathSensitive/GRBlockCounter.h" #include "clang/Analysis/PathSensitive/GRBlockCounter.h"
#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/OwningPtr.h"
namespace clang { namespace clang {
class GRStmtNodeBuilderImpl; class GRStmtNodeBuilderImpl;
@ -28,6 +30,15 @@ class GRIndirectGotoNodeBuilderImpl;
class GRWorkList; class GRWorkList;
class LabelStmt; class LabelStmt;
//===----------------------------------------------------------------------===//
/// GREngineImpl - Implements the core logic of the graph-reachability analysis.
/// It traverses the CFG and generates the ExplodedGraph. Program "states"
/// are treated as opaque void pointers. The template class GREngine
/// (which subclasses GREngineImpl) provides the matching component
/// to the engine that knows the actual types for states. Note that this
/// engine only dispatches to transfer functions as the statement and
/// block-level. The analyses themselves must implement any transfer
/// function logic and the sub-expression level (if any).
class GREngineImpl { class GREngineImpl {
protected: protected:
friend class GRStmtNodeBuilderImpl; friend class GRStmtNodeBuilderImpl;
@ -262,19 +273,6 @@ public:
GREngineImpl* eng) GREngineImpl* eng)
: Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
class Iterator;
class Destination {
LabelStmt* L;
CFGBlock* B;
friend class Iterator;
Destination(LabelStmt* l, CFGBlock* b) : L(l), B(b) {}
public:
CFGBlock* getBlock() const { return B; }
LabelStmt* getLabel() const { return L; }
};
class Iterator { class Iterator {
CFGBlock::succ_iterator I; CFGBlock::succ_iterator I;
@ -286,13 +284,19 @@ public:
Iterator& operator++() { ++I; return *this; } Iterator& operator++() { ++I; return *this; }
bool operator!=(const Iterator& X) const { return I != X.I; } bool operator!=(const Iterator& X) const { return I != X.I; }
Destination operator*(); LabelStmt* getLabel() const {
return llvm::cast<LabelStmt>((*I)->getLabel());
}
CFGBlock* getBlock() const {
return *I;
}
}; };
Iterator begin(); Iterator begin() { return Iterator(DispatchBlock.succ_begin()); }
Iterator end(); Iterator end() { return Iterator(DispatchBlock.succ_end()); }
ExplodedNodeImpl* generateNodeImpl(const Destination& D, void* State, ExplodedNodeImpl* generateNodeImpl(const Iterator& I, void* State,
bool isSink); bool isSink);
inline Expr* getTarget() const { return E; } inline Expr* getTarget() const { return E; }
@ -312,18 +316,15 @@ public:
GRIndirectGotoNodeBuilder(GRIndirectGotoNodeBuilderImpl& nb) : NB(nb) {} GRIndirectGotoNodeBuilder(GRIndirectGotoNodeBuilderImpl& nb) : NB(nb) {}
typedef GRIndirectGotoNodeBuilderImpl::Iterator iterator; typedef GRIndirectGotoNodeBuilderImpl::Iterator iterator;
typedef GRIndirectGotoNodeBuilderImpl::Destination Destination;
inline iterator begin() { return NB.begin(); } inline iterator begin() { return NB.begin(); }
inline iterator end() { return NB.end(); } inline iterator end() { return NB.end(); }
inline Expr* getTarget() const { return NB.getTarget(); } inline Expr* getTarget() const { return NB.getTarget(); }
inline NodeTy* generateNode(const Destination& D, StateTy St, inline NodeTy* generateNode(const iterator& I, StateTy St, bool isSink=false){
bool isSink = false) {
void *state = GRTrait<StateTy>::toPtr(St); void *state = GRTrait<StateTy>::toPtr(St);
return static_cast<NodeTy*>(NB.generateNodeImpl(D, state, isSink)); return static_cast<NodeTy*>(NB.generateNodeImpl(I, state, isSink));
} }
inline StateTy getState() const { inline StateTy getState() const {