blob: b249c303cc588c78f32f1494cab0f83853ce4f22 [file] [log] [blame]
//===- ArrayBoundsCheck.h ---------------------------------------*- C++ -*----//
//
// The SAFECode Compiler
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements a static array bounds checking analysis pass.
//
//===----------------------------------------------------------------------===//
#ifndef ARRAY_BOUNDS_CHECK_H_
#define ARRAY_BOUNDS_CHECK_H_
#include "safecode/AllocatorInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/InstVisitor.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
namespace llvm {
/// This class defines the interface of array bounds checking.
class ArrayBoundsCheckGroup {
public:
static char ID;
/// Determine whether a particular GEP instruction is always safe of not.
virtual bool isGEPSafe(GetElementPtrInst * GEP) { return false; }
virtual ~ArrayBoundsCheckGroup() = 0;
};
/// This is the dummy version of array bounds checking. It simply assumes that
/// every GEP instruction is unsafe.
class ArrayBoundsCheckDummy : public ArrayBoundsCheckGroup,
public ImmutablePass {
public:
static char ID;
ArrayBoundsCheckDummy() : ImmutablePass(ID) {}
/// When chaining analyses, changing the pointer to the correct pass
virtual void *getAdjustedAnalysisPointer(const void * ID) {
if (ID == (&ArrayBoundsCheckGroup::ID))
return (ArrayBoundsCheckGroup*)this;
return this;
}
};
/// ArrayBoundsCheckLocal - It tries to prove a GEP is safe only based on local
/// information, that is, the size of global variables and the size of objects
/// being allocated inside a function.
class ArrayBoundsCheckLocal : public FunctionPass,
public InstVisitor<ArrayBoundsCheckLocal> {
public:
static char ID;
ArrayBoundsCheckLocal() : FunctionPass(ID) {}
virtual bool isGEPSafe(GetElementPtrInst * GEP);
virtual void getAnalysisUsage(AnalysisUsage & AU) const {
AU.addRequired<DataLayout>();
AU.addRequired<AllocatorInfoPass>();
AU.addRequired<ScalarEvolution>();
AU.setPreservesAll();
}
virtual bool runOnFunction(Function & F);
virtual void releaseMemory() {
SafeGEPs.clear();
}
/// When chaining analyses, changing the pointer to the correct pass
virtual void *getAdjustedAnalysisPointer(const void * ID) {
if (ID == (&ArrayBoundsCheckGroup::ID))
return (ArrayBoundsCheckGroup*)this;
return this;
}
void visitGetElementPtrInst (GetElementPtrInst & GEP);
private:
// Required passes
DataLayout * TD;
ScalarEvolution * SE;
// Container holding safe GEPs
std::set<GetElementPtrInst *> SafeGEPs;
};
}
#endif