void local_SSAt::assign_rec( const exprt &lhs, const exprt &rhs, const exprt &guard, locationt loc) { const typet &type=ns.follow(lhs.type()); if(is_symbol_struct_member(lhs, ns)) { if(type.id()==ID_struct) { // need to split up const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { member_exprt new_lhs(lhs, it->get_name(), it->type()); member_exprt new_rhs(rhs, it->get_name(), it->type()); assign_rec(new_lhs, new_rhs, guard, loc); } return; } ssa_objectt lhs_object(lhs, ns); const std::set<ssa_objectt> &assigned= assignments.get(loc); if(assigned.find(lhs_object)!=assigned.end()) { exprt ssa_rhs=read_rhs(rhs, loc); const symbol_exprt ssa_symbol=name(lhs_object, OUT, loc); equal_exprt equality(ssa_symbol, ssa_rhs); nodes[loc].equalities.push_back(equality); } } else if(lhs.id()==ID_index) { const index_exprt &index_expr=to_index_expr(lhs); exprt ssa_array=index_expr.array(); exprt new_rhs=with_exprt(ssa_array, index_expr.index(), rhs); assign_rec(index_expr.array(), new_rhs, guard, loc); } else if(lhs.id()==ID_member) { // These are non-flattened struct or union members. const member_exprt &member_expr=to_member_expr(lhs); const exprt &compound=member_expr.struct_op(); const typet &compound_type=ns.follow(compound.type()); if(compound_type.id()==ID_union) { union_exprt new_rhs(member_expr.get_component_name(), rhs, compound.type()); assign_rec(member_expr.struct_op(), new_rhs, guard, loc); } else if(compound_type.id()==ID_struct) { exprt member_name(ID_member_name); member_name.set(ID_component_name, member_expr.get_component_name()); with_exprt new_rhs(compound, member_name, rhs); assign_rec(compound, new_rhs, guard, loc); } } else if(lhs.id()==ID_complex_real) { assert(lhs.operands().size()==1); const exprt &op=lhs.op0(); const complex_typet &complex_type=to_complex_type(op.type()); exprt imag_op=unary_exprt(ID_complex_imag, op, complex_type.subtype()); complex_exprt new_rhs(rhs, imag_op, complex_type); assign_rec(op, new_rhs, guard, loc); } else if(lhs.id()==ID_complex_imag) { assert(lhs.operands().size()==1); const exprt &op=lhs.op0(); const complex_typet &complex_type=to_complex_type(op.type()); exprt real_op=unary_exprt(ID_complex_real, op, complex_type.subtype()); complex_exprt new_rhs(real_op, rhs, complex_type); assign_rec(op, new_rhs, guard, loc); } else if(lhs.id()==ID_if) { const if_exprt &if_expr=to_if_expr(lhs); assign_rec(if_expr.true_case(), rhs, and_exprt(guard, if_expr.cond()), loc); assign_rec(if_expr.false_case(), rhs, and_exprt(guard, not_exprt(if_expr.cond())), loc); } else if(lhs.id()==ID_byte_extract_little_endian || lhs.id()==ID_byte_extract_big_endian) { const byte_extract_exprt &byte_extract_expr=to_byte_extract_expr(lhs); exprt new_lhs=byte_extract_expr.op(); exprt new_rhs=byte_extract_exprt( byte_extract_expr.id(), rhs, byte_extract_expr.offset(), new_lhs.type()); assign_rec(new_lhs, new_rhs, guard, loc); } else throw "UNKNOWN LHS: "+lhs.id_string(); }
bool smt1_dect::string_to_expr_z3( const typet &type, const std::string &value, exprt &e) const { if(value.substr(0,2)=="bv") { std::string v=value.substr(2, value.find('[')-2); size_t p = value.find('[')+1; std::string w=value.substr(p, value.find(']')-p); std::string binary=integer2binary(string2integer(v,10), string2integer(w,10).to_ulong()); if(type.id()==ID_struct) { e=binary2struct(to_struct_type(type), binary); } else if(type.id()==ID_union) { e=binary2union(to_union_type(type), binary); } else { constant_exprt c(type); c.set_value(binary); e=c; } return true; } else if(value.substr(0,6)=="(const") // const arrays { std::string av = value.substr(7, value.length()-8); exprt ae; if(!string_to_expr_z3(type.subtype(), av, ae)) return false; array_of_exprt ao; ao.type() = typet("array"); ao.type().subtype()=ae.type(); ao.what() = ae; e = ao; return true; } else if(value.substr(0,6)=="(store") { size_t p1=value.rfind(' ')+1; size_t p2=value.rfind(' ', p1-2)+1; assert(p1!=std::string::npos && p2!=std::string::npos); std::string elem = value.substr(p1, value.size()-p1-1); std::string inx = value.substr(p2, p1-p2-1); std::string array = value.substr(7, p2-8); exprt old; if(!string_to_expr_z3(type, array, old)) return false; exprt where; if(!string_to_expr_z3(array_index_type(), inx, where)) return false; exprt new_val; if(!string_to_expr_z3(type.subtype(), elem, new_val)) return false; e = with_exprt(old, where, new_val); return true; } else if(value=="false") { e = false_exprt(); return true; } else if(value=="true") { e = true_exprt(); return true; } else if(value.substr(0,8)=="array_of") { // We assume that array_of has only concrete arguments... irep_idt id(value); array_of_mapt::const_iterator fit=array_of_map.begin(); while(fit!=array_of_map.end() && fit->second!=id) fit++; if(fit==array_of_map.end()) return false; e = fit->first; return true; } else if(type.id()==ID_rational) { constant_exprt result; result.type()=rational_typet(); if(value.substr(0,4)=="val!") result.set_value(value.substr(4)); else result.set_value(value); e = result; return true; } return false; }