klee/0002-Fix-getelementptr-for-array-or-vector-indices.patch

101 lines
3.7 KiB
Diff

From: Martin Nowack <martin_nowack@tu-dresden.de>
Date: Sun, 29 Oct 2017 22:06:16 +0100
Subject: Fix getelementptr for array or vector indices
Patch-mainline: no
Rewrote code based on: llvm::GEPOperator::accumulateConstantOffset():
Handle signed offset correctly.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
lib/Core/ExecutorUtil.cpp | 51 ++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/lib/Core/ExecutorUtil.cpp b/lib/Core/ExecutorUtil.cpp
index 4f51ecb6301b..92dee5ac3906 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;
}
--
2.15.0