00001 //===-- ExprEvaluator.cpp -------------------------------------------------===// 00002 // 00003 // The KLEE Symbolic Virtual Machine 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "klee/util/ExprEvaluator.h" 00011 00012 using namespace klee; 00013 00014 ExprVisitor::Action ExprEvaluator::evalRead(const UpdateList &ul, 00015 unsigned index) { 00016 for (const UpdateNode *un=ul.head; un; un=un->next) { 00017 ref<Expr> ui = visit(un->index); 00018 00019 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ui)) { 00020 if (CE->getConstantValue() == index) 00021 return Action::changeTo(visit(un->value)); 00022 } else { 00023 // update index is unknown, so may or may not be index, we 00024 // cannot guarantee value. we can rewrite to read at this 00025 // version though (mostly for debugging). 00026 00027 UpdateList fwd(ul.root, un, 0); 00028 return Action::changeTo(ReadExpr::create(fwd, 00029 ConstantExpr::alloc(index, Expr::Int32))); 00030 } 00031 } 00032 00033 return Action::changeTo(getInitialValue(*ul.root, index)); 00034 } 00035 00036 ExprVisitor::Action ExprEvaluator::visitRead(const ReadExpr &re) { 00037 ref<Expr> v = visit(re.index); 00038 00039 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(v)) { 00040 return evalRead(re.updates, CE->getConstantValue()); 00041 } else { 00042 return Action::doChildren(); 00043 } 00044 } 00045 00046 // we need to check for div by zero during partial evaluation, 00047 // if this occurs then simply ignore the 0 divisor and use the 00048 // original expression. 00049 ExprVisitor::Action ExprEvaluator::protectedDivOperation(const BinaryExpr &e) { 00050 ref<Expr> kids[2] = { visit(e.left), 00051 visit(e.right) }; 00052 00053 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(kids[1])) 00054 if (!CE->getConstantValue()) 00055 kids[1] = e.right; 00056 00057 if (kids[0]!=e.left || kids[1]!=e.right) { 00058 return Action::changeTo(e.rebuild(kids)); 00059 } else { 00060 return Action::skipChildren(); 00061 } 00062 } 00063 00064 ExprVisitor::Action ExprEvaluator::visitUDiv(const UDivExpr &e) { 00065 return protectedDivOperation(e); 00066 } 00067 ExprVisitor::Action ExprEvaluator::visitSDiv(const SDivExpr &e) { 00068 return protectedDivOperation(e); 00069 } 00070 ExprVisitor::Action ExprEvaluator::visitURem(const URemExpr &e) { 00071 return protectedDivOperation(e); 00072 } 00073 ExprVisitor::Action ExprEvaluator::visitSRem(const SRemExpr &e) { 00074 return protectedDivOperation(e); 00075 }
1.5.8