bool inv_object_storet::is_constant_address(const exprt &expr) { if(expr.id()==ID_address_of) if(expr.operands().size()==1) return is_constant_address_rec(expr.op0()); return false; }
void bv_refinementt::convert_floatbv_op(const exprt &expr, bvt &bv) { if(ns.follow(expr.type()).id()!=ID_floatbv || expr.operands().size()!=3) return SUB::convert_floatbv_op(expr, bv); add_approximation(expr, bv); }
std::size_t pointer_logict::add_object(const exprt &expr) { // remove any index/member if(expr.id()==ID_index) { assert(expr.operands().size()==2); return add_object(expr.op0()); } else if(expr.id()==ID_member) { assert(expr.operands().size()==1); return add_object(expr.op0()); } return objects.number(expr); }
bool simplify_exprt::simplify_ieee_float_relation(exprt &expr) { assert(expr.id()==ID_ieee_float_equal || expr.id()==ID_ieee_float_notequal); exprt::operandst &operands=expr.operands(); if(expr.type().id()!=ID_bool) return true; if(operands.size()!=2) return true; // types must match if(expr.op0().type()!=expr.op1().type()) return true; if(expr.op0().type().id()!=ID_floatbv) return true; // first see if we compare to a constant if(expr.op0().is_constant() && expr.op1().is_constant()) { ieee_floatt f0(to_constant_expr(expr.op0())); ieee_floatt f1(to_constant_expr(expr.op1())); if(expr.id()==ID_ieee_float_notequal) expr.make_bool(f0.ieee_not_equal(f1)); else if(expr.id()==ID_ieee_float_equal) expr.make_bool(f0.ieee_equal(f1)); else assert(false); return false; } if(expr.op0()==expr.op1()) { // x!=x is the same as saying isnan(op) exprt isnan(ID_isnan, bool_typet()); isnan.copy_to_operands(expr.op0()); if(expr.id()==ID_ieee_float_notequal) { } else if(expr.id()==ID_ieee_float_equal) isnan.make_not(); else assert(false); expr.swap(isnan); return false; } return true; }
bool inv_object_storet::is_constant_address_rec(const exprt &expr) { if(expr.id()==ID_symbol) return true; else if(expr.id()==ID_member) { assert(expr.operands().size()==1); return is_constant_address_rec(expr.op0()); } else if(expr.id()==ID_index) { assert(expr.operands().size()==2); if(expr.op1().is_constant()) return is_constant_address_rec(expr.op0()); } return false; }
void cvc_convt::convert_expr(const exprt &expr) { const exprt::operandst &op=expr.operands(); if(expr.id()==ID_implies) { if(op.size()!=2) throw "implication takes two operands"; out << "("; convert_expr(op[0]); out << ") => ("; convert_expr(op[1]); out << ")"; } else if(expr.id()==ID_constraint_select_one) { if(op.size()<2) throw "constraint_select_one takes at least two operands"; // TODO throw "cvc_convt::convert_expr needs constraint_select_one"; } else if(expr.id()==ID_or || expr.id()==ID_and || expr.id()==ID_xor || expr.id()==ID_nor || expr.id()==ID_nand) { if(op.empty()) throw "operator `"+expr.id_string()+"' takes at least one operand"; else if(op.size()==1) convert_expr(op[0]); else { forall_expr(it, op) { if(it!=op.begin()) { if(expr.id()==ID_or) out << " OR "; else if(expr.id()==ID_nor) out << " NOR "; else if(expr.id()==ID_and) out << " AND "; else if(expr.id()==ID_nand) out << " NAND "; else if(expr.id()==ID_xor) out << " XOR "; else assert(false); } out << "("; convert_expr(*it); out << ")"; } } } else if(expr.id()==ID_not)
void boolbvt::convert_div(const exprt &expr, bvt &bv) { if(expr.type().id()!=ID_unsignedbv && expr.type().id()!=ID_signedbv && expr.type().id()!=ID_fixedbv) return conversion_failed(expr, bv); unsigned width=boolbv_width(expr.type()); if(width==0) return conversion_failed(expr, bv); if(expr.operands().size()!=2) throw "division takes two operands"; if(expr.op0().type().id()!=expr.type().id() || expr.op1().type().id()!=expr.type().id()) return conversion_failed(expr, bv); bvt op0=convert_bv(expr.op0()); bvt op1=convert_bv(expr.op1()); if(op0.size()!=width || op1.size()!=width) throw "convert_div: unexpected operand width"; bvt res, rem; if(expr.type().id()==ID_fixedbv) { unsigned fraction_bits= to_fixedbv_type(expr.type()).get_fraction_bits(); bvt zeros; zeros.resize(fraction_bits, const_literal(false)); // add fraction_bits least-significant bits op0.insert(op0.begin(), zeros.begin(), zeros.end()); op1=bv_utils.sign_extension(op1, op1.size()+fraction_bits); bv_utils.divider(op0, op1, res, rem, bv_utilst::SIGNED); // cut it down again res.resize(width); } else { bv_utilst::representationt rep= expr.type().id()==ID_signedbv?bv_utilst::SIGNED: bv_utilst::UNSIGNED; bv_utils.divider(op0, op1, res, rem, rep); } bv=res; }
void cnf_join_binary(exprt &expr) { Forall_operands(it, expr) cnf_join_binary(*it); if(expr.id()==ID_and || expr.id()==ID_or || expr.id()==ID_xor || expr.id()==ID_bitand || expr.id()==ID_bitor || expr.id()==ID_bitxor) { exprt tmp; if(expr.operands().size()==1) { tmp.swap(expr.op0()); expr.swap(tmp); } else { unsigned count=0; forall_operands(it, expr) { if(it->id()==expr.id()) count+=it->operands().size(); else count++; } tmp.operands().reserve(count); Forall_operands(it, expr) { if(it->id()==expr.id()) { Forall_operands(it2, *it) tmp.move_to_operands(*it2); } else tmp.move_to_operands(*it); } expr.operands().swap(tmp.operands()); } }
std::set<symbol_exprt> concurrency_aware_abstractort::targets_of_lvalue(const exprt& lvalue, goto_programt::const_targett program_location) { std::set<symbol_exprt> result; if(lvalue.id() == ID_index) { exprt array_name = lvalue.op0(); if(array_name.id() == ID_symbol) { result.insert(to_symbol_expr(array_name)); } else { return targets_of_lvalue(array_name, program_location); } } else if(lvalue.id() == ID_member) { assert(lvalue.operands().size() == 1); return targets_of_lvalue(lvalue.op0(), program_location); } else if(lvalue.id() == ID_symbol) { result.insert(to_symbol_expr(lvalue)); } else if(lvalue.id() == ID_dereference) { // We would like to add anything the pointer can point to, // but not the pointer itself value_setst::valuest value_set; pointer_info.get_values(program_location, lvalue.op0(), value_set); for(value_setst::valuest::iterator it = value_set.begin(); it != value_set.end(); it++) { if(it->id() != ID_object_descriptor) { // TODO: We may need to deal with this situation more carefully continue; } object_descriptor_exprt& object_descriptor = to_object_descriptor_expr(*it); if(object_descriptor.offset() != from_integer(0, index_type())) { std::cout << "Pointer " << from_expr(lvalue.op0()) << " can point to " << from_expr(*it) << " at line " << program_location->location.get_line() << ", we cannot handle this" << std::endl; exit(1); } if(object_descriptor.object().id() != ID_symbol) { std::cout << "Pointer " << from_expr(lvalue.op0()) << " can point to " << from_expr(*it) << " at line " << program_location->location.get_line() << ", we cannot handle this" << std::endl; exit(1); } result.insert(to_symbol_expr(object_descriptor.object())); } } else { std::cout << "Cannot currently handle lvalue: " << from_expr(lvalue) << std::endl; assert(false); } return result; }
void invariant_sett::strengthen_rec(const exprt &expr) { if(expr.type().id()!=ID_bool) throw "non-Boolean argument to strengthen()"; #if 0 std::cout << "S: " << from_expr(*ns, "", expr) << '\n'; #endif if(is_false) { // we can't get any stronger return; } if(expr.is_true()) { // do nothing, it's useless } else if(expr.is_false()) { // wow, that's strong make_false(); } else if(expr.id()==ID_not) { // give up, we expect NNF } else if(expr.id()==ID_and) { forall_operands(it, expr) strengthen_rec(*it); } else if(expr.id()==ID_le || expr.id()==ID_lt) { assert(expr.operands().size()==2); // special rule: x <= (a & b) // implies: x<=a && x<=b if(expr.op1().id()==ID_bitand) { const exprt &bitand_op=expr.op1(); forall_operands(it, bitand_op) { exprt tmp(expr); tmp.op1()=*it; strengthen_rec(tmp); } return; }
exprt dereferencet::dereference_rec( const exprt &address, const exprt &offset, const typet &type) { if(address.id()==ID_address_of) { const address_of_exprt &address_of_expr=to_address_of_expr(address); const exprt &object=address_of_expr.object(); return read_object(object, offset, type); } else if(address.id()==ID_typecast) { const typecast_exprt &typecast_expr=to_typecast_expr(address); return dereference_typecast(typecast_expr, offset, type); } else if(address.id()==ID_plus) { // pointer arithmetic if(address.operands().size()<2) throw "plus with less than two operands"; return dereference_plus(address, offset, type); } else if(address.id()==ID_if) { const if_exprt &if_expr=to_if_expr(address); return dereference_if(if_expr, offset, type); } else if(address.id()==ID_constant) { const typet result_type=ns.follow(address.type()).subtype(); // pointer-typed constant if(to_constant_expr(address).get_value()==ID_NULL) // NULL { // we turn this into (type *)0 exprt zero=gen_zero(index_type()); return dereference_rec( typecast_exprt(zero, address.type()), offset, type); } else throw "dereferencet: unexpected pointer constant "+address.pretty(); } else { throw "failed to dereference `"+address.id_string()+"'"; } }
void jsil_typecheckt::typecheck_expr_unary_num(exprt &expr) { if(expr.operands().size()!=1) { err_location(expr); error() << "operator `" << expr.id() << "' expects one operand" << eom; throw 0; } make_type_compatible(expr.op0(), floatbv_typet(), true); }
void bv_refinementt::convert_mod(const exprt &expr, bvt &bv) { // we catch any mod // unless it's integer + constant assert(expr.operands().size()==2); if(expr.op1().is_constant()) return SUB::convert_mod(expr, bv); add_approximation(expr, bv); }
std::string expr2javat::convert_java_instanceof( const exprt &src, unsigned precedence) { if(src.operands().size()!=2) { unsigned precedence; return convert_norep(src, precedence); } return convert(src.op0())+" instanceof "+convert(src.op1().type()); }
void gen_binary(exprt &expr, const std::string &id, bool default_value) { if(expr.operands().size()==0) { if(default_value) expr.make_true(); else expr.make_false(); } else if(expr.operands().size()==1) { exprt tmp; tmp.swap(expr.op0()); expr.swap(tmp); } else { expr.id(id); expr.type()=typet("bool"); } }
bool value_sett::eval_pointer_offset( exprt &expr, const namespacet &ns) const { bool mod=false; if(expr.id()==ID_pointer_offset) { assert(expr.operands().size()==1); object_mapt reference_set; get_value_set(expr.op0(), reference_set, ns, true); exprt new_expr; mp_integer previous_offset=0; const object_map_dt &object_map=reference_set.read(); for(object_map_dt::const_iterator it=object_map.begin(); it!=object_map.end(); it++) if(!it->second.offset_is_set) return false; else { const exprt &object=object_numbering[it->first]; mp_integer ptr_offset=compute_pointer_offset(object, ns); if(ptr_offset<0) return false; ptr_offset+=it->second.offset; if(mod && ptr_offset!=previous_offset) return false; new_expr=from_integer(ptr_offset, index_type()); previous_offset=ptr_offset; mod=true; } if(mod) expr.swap(new_expr); } else { Forall_operands(it, expr) mod=eval_pointer_offset(*it, ns) || mod; } return mod; }
literalt boolbvt::convert_quantifier(const exprt &expr) { if(expr.operands().size()!=3) return SUB::convert_rest(expr); literalt l=prop.new_variable(); quantifier_list.push_back(quantifiert()); quantifier_list.back().l=l; quantifier_list.back().expr=expr; return l; }
void path_slicert::get_symbols(const exprt &expr, string_sett &s) { if(expr.id()==ID_symbol) { s.insert(to_symbol_expr(expr).get_identifier()); } else if(expr.id()==ID_index) { assert(expr.operands().size()==2); string_sett tmp; get_symbols(expr.op0(), tmp); get_symbols(expr.op1(), s); for(string_sett::const_iterator it=tmp.begin(); it!=tmp.end(); it++) s.insert(id2string(*it)+"[]"); } else if(expr.id()==ID_member) { assert(expr.operands().size()==1); string_sett tmp; get_symbols(expr.op0(), tmp); std::string suffix="."+expr.get_string(ID_component_name); for(string_sett::const_iterator it=tmp.begin(); it!=tmp.end(); it++) s.insert(id2string(*it)+suffix); } else forall_operands(it, expr) get_symbols(*it, s); }
bool simplify_exprt::simplify_isnormal(exprt &expr) { if(expr.operands().size()!=1) return true; if(expr.op0().is_constant()) { ieee_floatt value(to_constant_expr(expr.op0())); expr.make_bool(value.is_normal()); return false; } return true; }
bvt bv_refinementt::convert_floatbv_op(const exprt &expr) { if(!do_arithmetic_refinement) return SUB::convert_floatbv_op(expr); if(ns.follow(expr.type()).id()!=ID_floatbv || expr.operands().size()!=3) return SUB::convert_floatbv_op(expr); bvt bv; add_approximation(expr, bv); return bv; }
exprt c_typecheck_baset::do_initializer_list( const exprt &value, const typet &type, bool force_constant) { assert(value.id()==ID_initializer_list); if(type.id()==ID_symbol) return do_initializer_list( value, follow(type), force_constant); exprt result; if(type.id()==ID_struct || type.id()==ID_array || type.id()==ID_union) { // start with zero everywhere result=zero_initializer(type, value.location()); } else if(type.id()==ID_incomplete_array) { // start with empty array result=exprt(ID_array, type); result.location()=value.location(); } else { // The initializer for a scalar shall be a single expression, // * optionally enclosed in braces. * if(value.operands().size()==1) return do_initializer_rec(value.op0(), type, force_constant); err_location(value); str << "cannot initialize `" << to_string(type) << "' with " "an initializer list"; throw 0; } designatort current_designator; designator_enter(type, current_designator); forall_operands(it, value) { do_designated_initializer( result, current_designator, *it, force_constant); // increase designator -- might go up increment_designator(current_designator); }
void preconditiont::compute_address_of(exprt &dest) { if(dest.id()==ID_symbol) { // leave alone } else if(dest.id()==ID_index) { assert(dest.operands().size()==2); compute_address_of(dest.op0()); compute(dest.op1()); } else if(dest.id()==ID_member) { assert(dest.operands().size()==1); compute_address_of(dest.op0()); } else if(dest.id()==ID_dereference) { assert(dest.operands().size()==1); compute(dest.op0()); } }
static bool has_dereference(const exprt &expr) { if (expr.id() == "dereference") return true; else if (expr.id() == "index" && expr.op0().type().id() == "pointer") // This is an index of a pointer, which is a dereference return true; else if (expr.operands().size() > 0 && expr.op0().is_not_nil()) // Recurse through all subsequent source objects, which are always operand // zero. return has_dereference(expr.op0()); else return false; }
void jsil_typecheckt::typecheck_exp_binary_equal(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } // operands can be of any types expr.type()=bool_typet(); }
void jsil_typecheckt::typecheck_expr_base(exprt &expr) { if(expr.operands().size()!=1) { err_location(expr); error() << "operator `" << expr.id() << "' expects single operand" << eom; throw 0; } make_type_compatible(expr.op0(), jsil_reference_type(), true); expr.type()=jsil_value_type(); }
exprt make_va_list(const exprt &expr) { // we first strip any typecast if(expr.id()==ID_typecast) return make_va_list(to_typecast_expr(expr).op()); // if it's an address of an lvalue, we take that if(expr.id()==ID_address_of && expr.operands().size()==1 && is_lvalue(expr.op0())) return expr.op0(); return expr; }
void goto_checkt::overflow_check(const exprt &expr, const guardt &guard) { if (!options.get_bool_option("overflow-check")) return; // first, check type if (expr.type().id() != "signedbv") return; // add overflow subgoal exprt overflow("overflow-" + expr.id_string(), bool_typet()); overflow.operands() = expr.operands(); if (expr.id() == "typecast") { if (expr.operands().size() != 1) throw "typecast takes one operand"; const typet &old_type = expr.op0().type(); unsigned new_width = atoi(expr.type().width().c_str()); unsigned old_width = atoi(old_type.width().c_str()); if (old_type.id() == "unsignedbv") new_width--; if (new_width >= old_width) return; overflow.id(overflow.id_string() + "-" + i2string(new_width)); } overflow.make_not(); add_guarded_claim(overflow, "arithmetic overflow on " + expr.id_string(), "overflow", expr.find_location(), guard); }
void jsil_typecheckt::typecheck_expr_proto_obj(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands"; throw 0; } make_type_compatible(expr.op0(), jsil_object_type(), true); make_type_compatible(expr.op1(), jsil_object_type(), true); expr.type()=bool_typet(); }
void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } make_type_compatible(expr.op0(), floatbv_typet(), true); make_type_compatible(expr.op1(), floatbv_typet(), true); expr.type()=bool_typet(); }
void jsil_typecheckt::typecheck_expr_concatenation(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } make_type_compatible(expr.op0(), string_typet(), true); make_type_compatible(expr.op1(), string_typet(), true); expr.type()=string_typet(); }