aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Core
diff options
context:
space:
mode:
authorMartin Nowack <martin_nowack@tu-dresden.de>2017-10-29 22:06:16 +0100
committerCristian Cadar <c.cadar@imperial.ac.uk>2018-02-18 12:49:41 +0000
commitf751f9351f0176a3109e260a6e8e9727fc9fb4ea (patch)
tree802068a39fe5266b5d80719001becae26f4f0593 /lib/Core
parent51183b4370eb2a081c440b6ff32acc4e5f50890e (diff)
downloadklee-f751f9351f0176a3109e260a6e8e9727fc9fb4ea.tar.gz
Fix getelementptr for array or vector indices
Rewrote code based on: llvm::GEPOperator::accumulateConstantOffset(): Handle signed offset correctly.
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/ExecutorUtil.cpp51
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;
}