OBS-URL: https://build.opensuse.org/package/show/devel:tools:statica/klee?expand=0&rev=32
101 lines
3.7 KiB
Diff
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
|
|
|