ExprEvaluator.cpp

Go to the documentation of this file.
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 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8