diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-05-18 21:49:12 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-05-18 21:49:12 +0000 |
commit | 243a217c15fdbf920f91fabfae460f957b25e0ec (patch) | |
tree | 6ea280c835169281ccf8d545b0b484bad949a7e6 /lib | |
parent | bbaba2f7c94050712802b3ae39d92d727853ffc9 (diff) | |
download | klee-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')
-rw-r--r-- | lib/Core/Executor.cpp | 22 |
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()"); } } |