diff options
author | Martin Nowack <martin_nowack@tu-dresden.de> | 2017-10-29 22:06:16 +0100 |
---|---|---|
committer | Cristian Cadar <c.cadar@imperial.ac.uk> | 2018-02-18 12:49:41 +0000 |
commit | f751f9351f0176a3109e260a6e8e9727fc9fb4ea (patch) | |
tree | 802068a39fe5266b5d80719001becae26f4f0593 | |
parent | 51183b4370eb2a081c440b6ff32acc4e5f50890e (diff) | |
download | klee-f751f9351f0176a3109e260a6e8e9727fc9fb4ea.tar.gz |
Fix getelementptr for array or vector indices
Rewrote code based on: llvm::GEPOperator::accumulateConstantOffset(): Handle signed offset correctly.
-rw-r--r-- | lib/Core/ExecutorUtil.cpp | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/lib/Core/ExecutorUtil.cpp b/lib/Core/ExecutorUtil.cpp index 4f51ecb6..92dee5ac 100644 --- a/lib/Core/ExecutorUtil.cpp +++ b/lib/Core/ExecutorUtil.cpp @@ -19,18 +19,22 @@ #include "klee/Internal/Module/KModule.h" #include "klee/Internal/Support/ErrorHandling.h" -#include "klee/util/GetElementPtrTypeIterator.h" -#include "llvm/IR/Function.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" -#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Operator.h" +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) +#include "llvm/Support/GetElementPtrTypeIterator.h" +#else +#include "llvm/IR/GetElementPtrTypeIterator.h" +#endif #include "llvm/Support/raw_ostream.h" #include <cassert> -using namespace klee; using namespace llvm; namespace klee { @@ -188,34 +192,31 @@ namespace klee { case Instruction::GetElementPtr: { ref<ConstantExpr> base = op1->ZExt(Context::get().getPointerWidth()); - for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce); ii != ie; ++ii) { - ref<ConstantExpr> addend = - ConstantExpr::alloc(0, Context::get().getPointerWidth()); - - if (StructType *st = dyn_cast<StructType>(*ii)) { - const StructLayout *sl = kmodule->targetData->getStructLayout(st); - const ConstantInt *ci = cast<ConstantInt>(ii.getOperand()); - - addend = ConstantExpr::alloc(sl->getElementOffset((unsigned) - ci->getZExtValue()), - Context::get().getPointerWidth()); - } else { - const SequentialType *set = cast<SequentialType>(*ii); - ref<ConstantExpr> index = + ref<ConstantExpr> indexOp = evalConstant(cast<Constant>(ii.getOperand()), ki); - unsigned elementSize = - kmodule->targetData->getTypeStoreSize(set->getElementType()); + if (indexOp->isZero()) + continue; - index = index->ZExt(Context::get().getPointerWidth()); - addend = index->Mul(ConstantExpr::alloc(elementSize, - Context::get().getPointerWidth())); + // Handle a struct index, which adds its field offset to the pointer. + if (StructType *STy = dyn_cast<StructType>(*ii)) { + unsigned ElementIdx = indexOp->getZExtValue(); + const StructLayout *SL = kmodule->targetData->getStructLayout(STy); + base = base->Add( + ConstantExpr::alloc(APInt(Context::get().getPointerWidth(), + SL->getElementOffset(ElementIdx)))); + continue; } - base = base->Add(addend); + // For array or vector indices, scale the index by the size of the type. + // Indices can be negative + base = base->Add(indexOp->SExt(Context::get().getPointerWidth()) + ->Mul(ConstantExpr::alloc( + APInt(Context::get().getPointerWidth(), + kmodule->targetData->getTypeAllocSize( + ii.getIndexedType()))))); } - return base; } |