about summary refs log tree commit diff homepage
path: root/lib/Core
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-05-18 21:49:12 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-05-18 21:49:12 +0000
commit243a217c15fdbf920f91fabfae460f957b25e0ec (patch)
tree6ea280c835169281ccf8d545b0b484bad949a7e6 /lib/Core
parentbbaba2f7c94050712802b3ae39d92d727853ffc9 (diff)
downloadklee-243a217c15fdbf920f91fabfae460f957b25e0ec.tar.gz
Add ConstantStruct support to Executor::evalConstant
git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@131586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/Executor.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index aa0b43d2..0dbaab80 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -945,8 +945,28 @@ ref<klee::ConstantExpr> Executor::evalConstant(Constant *c) {
       return Expr::createPointer(0);
     } else if (isa<UndefValue>(c) || isa<ConstantAggregateZero>(c)) {
       return ConstantExpr::create(0, getWidthForLLVMType(c->getType()));
+    } else if (const ConstantStruct *cs = dyn_cast<ConstantStruct>(c)) {
+      const StructLayout *sl = kmodule->targetData->getStructLayout(cs->getType());
+      llvm::SmallVector<ref<Expr>, 4> kids;
+      for (unsigned i = cs->getNumOperands(); i != 0; --i) {
+        unsigned op = i-1;
+        ref<Expr> kid = evalConstant(cs->getOperand(op));
+
+        uint64_t thisOffset = sl->getElementOffsetInBits(op),
+                 nextOffset = (op == cs->getNumOperands() - 1)
+                              ? sl->getSizeInBits()
+                              : sl->getElementOffsetInBits(op+1);
+        if (nextOffset-thisOffset > kid->getWidth()) {
+          uint64_t paddingWidth = nextOffset-thisOffset-kid->getWidth();
+          kids.push_back(ConstantExpr::create(0, paddingWidth));
+        }
+
+        kids.push_back(kid);
+      }
+      ref<Expr> res = ConcatExpr::createN(kids.size(), kids.data());
+      return cast<ConstantExpr>(res);
     } else {
-      // Constant{Array,Struct,Vector}
+      // Constant{Array,Vector}
       assert(0 && "invalid argument to evalConstant()");
     }
   }