void rd_range_domaint::assign_if( const namespacet &ns, locationt from, const if_exprt &if_expr, const mp_integer &size) { if(if_expr.cond().is_false()) assign(ns, from, if_expr.false_case(), size); else if(if_expr.cond().is_true()) assign(ns, from, if_expr.true_case(), size); else { rd_range_domaint false_case(*this); assign(ns, from, if_expr.false_case(), size); values.swap(false_case.values); assign(ns, from, if_expr.true_case(), size); merge(false_case, from); } }
exprt dereferencet::dereference_if( const if_exprt &expr, const exprt &offset, const typet &type) { // push down the if, do recursive call exprt true_case=dereference_rec(expr.true_case(), offset, type); exprt false_case=dereference_rec(expr.false_case(), offset, type); return if_exprt(expr.cond(), true_case, false_case); }
bvt boolbvt::convert_if(const if_exprt &expr) { std::size_t width=boolbv_width(expr.type()); if(width==0) return bvt(); // An empty bit-vector if. literalt cond=convert(expr.cond()); const bvt &op1_bv=convert_bv(expr.true_case()); const bvt &op2_bv=convert_bv(expr.false_case()); if(op1_bv.size()!=width || op2_bv.size()!=width) throw "operand size mismatch for if "+expr.pretty(); return bv_utils.select(cond, op1_bv, op2_bv); }
void goto_convertt::do_function_call_if( const exprt &lhs, const if_exprt &function, const exprt::operandst &arguments, goto_programt &dest) { // case split // c?f():g() //-------------------- // v: if(!c) goto y; // w: f(); // x: goto z; // y: g(); // z: ; // do the v label goto_programt tmp_v; goto_programt::targett v=tmp_v.add_instruction(); // do the x label goto_programt tmp_x; goto_programt::targett x=tmp_x.add_instruction(); // do the z label goto_programt tmp_z; goto_programt::targett z=tmp_z.add_instruction(); z->make_skip(); // y: g(); goto_programt tmp_y; goto_programt::targett y; do_function_call(lhs, function.false_case(), arguments, tmp_y); if(tmp_y.instructions.empty()) y=tmp_y.add_instruction(SKIP); else y=tmp_y.instructions.begin(); // v: if(!c) goto y; v->make_goto(y); v->guard=function.cond(); v->guard.make_not(); v->source_location=function.cond().source_location(); // w: f(); goto_programt tmp_w; do_function_call(lhs, function.true_case(), arguments, tmp_w); if(tmp_w.instructions.empty()) tmp_w.add_instruction(SKIP); // x: goto z; x->make_goto(z); dest.destructive_append(tmp_v); dest.destructive_append(tmp_w); dest.destructive_append(tmp_x); dest.destructive_append(tmp_y); dest.destructive_append(tmp_z); }
void arrayst::add_array_constraints_if( const index_sett &index_set, const if_exprt &expr) { // we got x=(c?a:b) literalt cond_lit=convert(expr.cond()); // get other array index applications // and add c => x[i]=a[i] // !c => x[i]=b[i] // first do true case for(index_sett::const_iterator it=index_set.begin(); it!=index_set.end(); it++) { index_exprt index_expr1; index_expr1.type()=ns.follow(expr.type()).subtype(); index_expr1.array()=expr; index_expr1.index()=*it; index_exprt index_expr2; index_expr2.type()=ns.follow(expr.type()).subtype(); index_expr2.array()=expr.true_case(); index_expr2.index()=*it; assert(index_expr1.type()==index_expr2.type()); // add implication bvt bv; bv.push_back(prop.lnot(cond_lit)); bv.push_back(convert(equality_exprt(index_expr1, index_expr2))); prop.lcnf(bv); } // now the false case for(index_sett::const_iterator it=index_set.begin(); it!=index_set.end(); it++) { index_exprt index_expr1; index_expr1.type()=ns.follow(expr.type()).subtype(); index_expr1.array()=expr; index_expr1.index()=*it; index_exprt index_expr2; index_expr2.type()=ns.follow(expr.type()).subtype(); index_expr2.array()=expr.false_case(); index_expr2.index()=*it; assert(index_expr1.type()==index_expr2.type()); // add implication bvt bv; bv.push_back(cond_lit); bv.push_back(convert(equality_exprt(index_expr1, index_expr2))); prop.lcnf(bv); } }