Hooked up the GRConstants analysis to the driver.

Fixed some compilation errors with GREngine that showed up during
template instantiation.

llvm-svn: 46074
This commit is contained in:
Ted Kremenek 2008-01-16 18:18:48 +00:00
parent aebbe4700a
commit 2e12c2e790
8 changed files with 46 additions and 31 deletions

View File

@ -288,4 +288,14 @@ void GRConstants::VisitBinAdd(BinaryOperator* B) {
void GRConstants::VisitBinSub(BinaryOperator* B) {
AddBinding(B, GetBinding(B->getLHS()) - GetBinding(B->getRHS()));
}
//===----------------------------------------------------------------------===//
// Driver.
//===----------------------------------------------------------------------===//
namespace clang {
void RunGRConstants(CFG& cfg) {
GREngine<GRConstants> Engine(cfg);
Engine.ExecuteWorkList();
}
}

View File

@ -44,6 +44,10 @@ public:
};
} // end anonymous namespace
// Place the dstor for GRWorkList here because it contains virtual member
// functions, and we the code for the dstor generated in one compilation unit.
GRWorkList::~GRWorkList() {}
GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.

View File

@ -19,6 +19,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/CFG.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/Analyses/GRConstants.h"
#include "clang/Analysis/LocalCheckers.h"
#include "llvm/Support/Streams.h"
#include <fstream>
@ -562,22 +563,21 @@ ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
}
//===----------------------------------------------------------------------===//
// GRConstProp - Perform intra-procedural, path-sensitive constant propagation.
// GRConstants - Perform intra-procedural, path-sensitive constant propagation.
namespace {
class GRConstPropVisitor : public CFGVisitor {
class GRConstantsVisitor : public CFGVisitor {
public:
virtual void Initialize(ASTContext &Context) {}
virtual void VisitCFG(CFG& C) {
// FIXME: Implement.
assert (false && "Not yet implemented.");
RunGRConstants(C);
}
};
} // end anonymous namespace
ASTConsumer *clang::CreateGRConstProp() {
return new GRConstPropVisitor();
ASTConsumer *clang::CreateGRConstants() {
return new GRConstantsVisitor();
}
//===----------------------------------------------------------------------===//

View File

@ -39,7 +39,7 @@ ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
ASTConsumer *CreateGRConstProp();
ASTConsumer *CreateGRConstants();
ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);

View File

@ -64,7 +64,7 @@ enum ProgActions {
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
AnalysisLiveVariables, // Print results of live-variable analysis.
AnalysisGRConstProp, // Perform graph-reachability constant prop.
AnalysisGRConstants, // Perform graph-reachability constant prop.
WarnDeadStores, // Run DeadStores checker on parsed ASTs.
WarnDeadStoresCheck, // Check diagnostics for "DeadStores".
WarnUninitVals, // Run UnitializedVariables checker.
@ -109,7 +109,7 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
"Flag warnings of stores to dead variables."),
clEnumValN(WarnUninitVals, "warn-uninit-values",
"Flag warnings of uses of unitialized variables."),
clEnumValN(AnalysisGRConstProp, "gr-const-prop",
clEnumValN(AnalysisGRConstants, "gr-const-prop",
"Perform path-sensitive constant propagation."),
clEnumValN(TestSerialization, "test-pickling",
"Run prototype serializtion code."),
@ -947,8 +947,8 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
case WarnUninitVals:
return CreateUnitValsChecker(Diag);
case AnalysisGRConstProp:
return CreateGRConstProp();
case AnalysisGRConstants:
return CreateGRConstants();
case TestSerialization:
return CreateSerializationTest(Diag, FileMgr, LangOpts);

View File

@ -40,9 +40,17 @@ protected:
enum { Size1 = 0x0, SizeOther = 0x1, Infeasible = 0x2, Flags = 0x3 };
uintptr_t P;
unsigned getKind() const { return P & Flags; }
void* getPtr() const { return reinterpret_cast<void*>(P & ~Flags); }
ExplodedNodeImpl* getNode() const;
unsigned getKind() const {
return P & Flags;
}
void* getPtr() const {
return reinterpret_cast<void*>(P & ~Flags);
}
ExplodedNodeImpl* getNode() const {
return reinterpret_cast<ExplodedNodeImpl*>(getPtr());
}
public:
NodeGroup() : P(0) {}
@ -136,8 +144,8 @@ class ExplodedNode : public ExplodedNodeImpl {
public:
/// Construct a ExplodedNodeImpl with the given node ID, program edge,
/// and state.
explicit ExplodedNode(unsigned ID, const ProgramPoint& loc, StateTy state)
: ExplodedNodeImpl(ID, loc, GRTrait<StateTy>::toPtr(state)) {}
explicit ExplodedNode(const ProgramPoint& loc, StateTy state)
: ExplodedNodeImpl(loc, GRTrait<StateTy>::toPtr(state)) {}
/// getState - Returns the state associated with the node.
inline StateTy getState() const {
@ -186,13 +194,7 @@ protected:
typedef llvm::DenseMap<ProgramPoint,void*> EdgeNodeSetMap;
typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
/// NodeCounter - The number of nodes that have been created, although
/// this need not be the current number of nodes in the graph that
/// are reachable from the roots. This counter is used to assign a unique
/// number to each node (which is useful for debugging).
unsigned NodeCounter;
/// Roots - The roots of the simulation graph. Usually there will be only
/// one, but clients are free to establish multiple subgraphs within a single
/// SimulGraph. Moreover, these subgraphs can often merge when paths from
@ -232,7 +234,6 @@ public:
unsigned num_roots() const { return Roots.size(); }
unsigned num_eops() const { return EndNodes.size(); }
unsigned getCounter() const { return NodeCounter; }
};
template <typename CHECKER>
@ -248,7 +249,7 @@ protected:
protected:
virtual ExplodedNodeImpl*
getNodeImpl(const ProgramPoint& L, void* State, bool* IsNew) {
return getNode(L,GRTrait<StateTy>::toState(State),IsNew);
return getNode(L, GRTrait<StateTy>::toState(State), IsNew);
}
public:
@ -275,15 +276,15 @@ public:
void* InsertPos = 0;
StateTy::Profile(profile, State);
NodeTy* V = VSet.FindNodeOrInsertPos(profile, InsertPos);
NodeTy* V = VSet->FindNodeOrInsertPos(profile, InsertPos);
if (!V) {
// Allocate a new node.
V = (NodeTy*) Allocator.Allocate<NodeTy>();
new (V) NodeTy(NodeCounter++, L, State);
new (V) NodeTy(L, State);
// Insert the node into the node set and return it.
VSet.InsertNode(V, InsertPos);
VSet->InsertNode(V, InsertPos);
if (IsNew) *IsNew = true;
}

View File

@ -173,7 +173,7 @@ protected:
virtual void* getInitialState() {
return GRTrait<StateTy>::toPtr(getCheckerState()->getInitialState());
return GRTrait<StateTy>::toPtr(getCheckerState().getInitialState());
}
virtual void* ProcessEOP(CFGBlock* Blk, void* State) {

View File

@ -38,7 +38,7 @@ public:
class GRWorkList {
public:
virtual ~GRWorkList() = 0;
virtual ~GRWorkList();
virtual bool hasWork() const = 0;
virtual void Enqueue(const GRWorkListUnit& U) = 0;