//===-- ExprEvaluator.cpp -------------------------------------------------===// // // The KLEE Symbolic Virtual Machine // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "klee/util/ExprEvaluator.h" using namespace klee; ExprVisitor::Action ExprEvaluator::evalRead(const UpdateList &ul, unsigned index) { for (const UpdateNode *un=ul.head; un; un=un->next) { ref ui = visit(un->index); if (ui.isConstant()) { if (ui.getConstantValue() == index) return Action::changeTo(visit(un->value)); } else { // update index is unknown, so may or may not be index, we // cannot guarantee value. we can rewrite to read at this // version though (mostly for debugging). UpdateList fwd(ul.root, un, 0); return Action::changeTo(ReadExpr::create(fwd, ConstantExpr::alloc(index, Expr::Int32))); } } return Action::changeTo(getInitialValue(*ul.root, index)); } ExprVisitor::Action ExprEvaluator::visitRead(const ReadExpr &re) { ref v = visit(re.index); if (v.isConstant()) { return evalRead(re.updates, v.getConstantValue()); } else { return Action::doChildren(); } } // we need to check for div by zero during partial evaluation, // if this occurs then simply ignore the 0 divisor and use the // original expression. ExprVisitor::Action ExprEvaluator::protectedDivOperation(const BinaryExpr &e) { ref kids[2] = { visit(e.left), visit(e.right) }; if (kids[1].isConstant() && !kids[1].getConstantValue()) kids[1] = e.right; if (kids[0]!=e.left || kids[1]!=e.right) { return Action::changeTo(e.rebuild(kids)); } else { return Action::skipChildren(); } } ExprVisitor::Action ExprEvaluator::visitUDiv(const UDivExpr &e) { return protectedDivOperation(e); } ExprVisitor::Action ExprEvaluator::visitSDiv(const SDivExpr &e) { return protectedDivOperation(e); } ExprVisitor::Action ExprEvaluator::visitURem(const URemExpr &e) { return protectedDivOperation(e); } ExprVisitor::Action ExprEvaluator::visitSRem(const SRemExpr &e) { return protectedDivOperation(e); }