void goto_program_dereferencet::dereference_instruction( goto_programt::targett target, bool checks_only) { current_target=target; #if 0 valid_local_variables=&target->local_variables; #endif goto_programt::instructiont &i=*target; dereference_expr(i.guard, checks_only, value_set_dereferencet::READ); if(i.is_assign()) { if(i.code.operands().size()!=2) throw "assignment expects two operands"; dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::WRITE); dereference_expr(i.code.op1(), checks_only, value_set_dereferencet::READ); } else if(i.is_function_call()) { code_function_callt &function_call=to_code_function_call(to_code(i.code)); if(function_call.lhs().is_not_nil()) dereference_expr(function_call.lhs(), checks_only, value_set_dereferencet::WRITE); dereference_expr(function_call.function(), checks_only, value_set_dereferencet::READ); dereference_expr(function_call.op2(), checks_only, value_set_dereferencet::READ); } else if(i.is_return()) { Forall_operands(it, i.code) dereference_expr(*it, checks_only, value_set_dereferencet::READ); } else if(i.is_other()) { const irep_idt &statement=i.code.get(ID_statement); if(statement==ID_expression) { if(i.code.operands().size()!=1) throw "expression expects one operand"; dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::READ); } else if(statement==ID_printf) { Forall_operands(it, i.code) dereference_expr(*it, checks_only, value_set_dereferencet::READ); } } }
void c_typecheck_baset::typecheck_asm(codet &code) { const irep_idt flavor=to_code_asm(code).get_flavor(); if(flavor==ID_gcc) { // These have 5 operands. // The first parameter is a string. // Parameters 1, 2, 3, 4 are lists of expressions. // Parameter 1: OutputOperands // Parameter 2: InputOperands // Parameter 3: Clobbers // Parameter 4: GotoLabels assert(code.operands().size()==5); typecheck_expr(code.op0()); for(unsigned i=1; i<code.operands().size(); i++) { exprt &list=code.operands()[i]; Forall_operands(it, list) typecheck_expr(*it); } } else if(flavor==ID_msc) { assert(code.operands().size()==1); typecheck_expr(code.op0()); } }
void modelchecker_smvt::instantiate_expression(exprt &expr) { Forall_operands(it, expr) instantiate_expression(*it); if(expr.id()==ID_predicate_symbol) { unsigned p=atoi(expr.get(ID_identifier).c_str()); expr.id(ID_symbol); expr.set(ID_identifier, variable_names[p]); } else if(expr.id()==ID_predicate_next_symbol) { unsigned p=atoi(expr.get(ID_identifier).c_str()); expr.id(ID_next_symbol); expr.set(ID_identifier, variable_names[p]); } else if(expr.id()==ID_nondet_symbol) { nondet_symbolst::const_iterator it= nondet_symbols.find( static_cast<const exprt &>(expr.find("expression"))); if(it==nondet_symbols.end()) throw "failed to find nondet_symbol"; typet type=expr.type(); expr=exprt(ID_symbol, type); expr.set(ID_identifier, it->second); } }
void base_type(exprt &expr, const namespacet &ns) { base_type(expr.type(), ns); Forall_operands(it, expr) base_type(*it, ns); }
void ansi_c_convertt::convert_expr(exprt &expr) { if(expr.id()==ID_sideeffect) { const irep_idt &statement=expr.get(ID_statement); if(statement==ID_statement_expression) { assert(expr.operands().size()==1); convert_code(to_code(expr.op0())); return; // done } } Forall_operands(it, expr) convert_expr(*it); if(expr.id()==ID_symbol) { expr.remove(ID_C_id_class); expr.remove(ID_C_base_name); } else if(expr.id()==ID_sizeof) { if(expr.operands().size()==0) { typet &type=static_cast<typet &>(expr.add(ID_type_arg)); convert_type(type); } } else if(expr.id()==ID_designated_initializer) { exprt &designator=static_cast<exprt &>(expr.add(ID_designator)); convert_expr(designator); } else if(expr.id()==ID_alignof) { if(expr.operands().size()==0) { typet &type=static_cast<typet &>(expr.add(ID_type_arg)); convert_type(type); } } else if(expr.id()==ID_gcc_builtin_va_arg) { convert_type(expr.type()); } else if(expr.id()==ID_generic_selection) { assert(expr.operands().size()==1); irept::subt &generic_associations= expr.add(ID_generic_associations).get_sub(); Forall_irep(it, generic_associations) { convert_expr(static_cast<exprt &>(it->add(ID_value))); convert_type(static_cast<typet &>(it->add(ID_type_arg))); }
void make_next_state(exprt &expr) { Forall_operands(it, expr) make_next_state(*it); if(expr.id()=="symbol") expr.id("next_symbol"); }
void make_next_state(exprt &expr) { Forall_operands(it, expr) make_next_state(*it); if(expr.id()==ID_symbol) expr.id(ID_next_symbol); }
void java_bytecode_typecheckt::typecheck_code(codet &code) { const irep_idt &statement=code.get_statement(); if(statement==ID_assign) { code_assignt &code_assign=to_code_assign(code); typecheck_expr(code_assign.lhs()); typecheck_expr(code_assign.rhs()); if(code_assign.lhs().type()!=code_assign.rhs().type()) code_assign.rhs().make_typecast(code_assign.lhs().type()); } else if(statement==ID_block) { Forall_operands(it, code) typecheck_code(to_code(*it)); } else if(statement==ID_label) { code_labelt &code_label=to_code_label(code); typecheck_code(code_label.code()); } else if(statement==ID_goto) { } else if(statement==ID_ifthenelse) { code_ifthenelset &code_ifthenelse=to_code_ifthenelse(code); typecheck_expr(code_ifthenelse.cond()); typecheck_code(code_ifthenelse.then_case()); if(code_ifthenelse.else_case().is_not_nil()) typecheck_code(code_ifthenelse.else_case()); } else if(statement==ID_switch) { code_switcht &code_switch = to_code_switch(code); typecheck_expr(code_switch.value()); } else if(statement==ID_return) { if(code.operands().size()==1) typecheck_expr(code.op0()); } else if(statement==ID_function_call) { code_function_callt &code_function_call=to_code_function_call(code); typecheck_expr(code_function_call.lhs()); typecheck_expr(code_function_call.function()); for(code_function_callt::argumentst::iterator a_it=code_function_call.arguments().begin(); a_it!=code_function_call.arguments().end(); a_it++) typecheck_expr(*a_it); } }
void replace_location( exprt &dest, const source_locationt &new_location) { Forall_operands(it, dest) replace_location(*it, new_location); if(dest.find(ID_C_source_location).is_not_nil()) replace_location(dest.add_source_location(), new_location); }
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()); } }
void preconditiont::compute_rec(exprt &dest) { if(dest.id()==ID_address_of) { // only do index! assert(dest.operands().size()==1); compute_address_of(dest.op0()); } else if(dest.id()==ID_symbol) { if(dest.get(ID_identifier)== s.get_original_name(SSA_step.ssa_lhs.get_identifier())) { dest=SSA_step.ssa_rhs; s.get_original_name(dest); } } else if(dest.id()==ID_dereference) { assert(dest.operands().size()==1); const irep_idt &lhs_identifier= s.get_original_name(SSA_step.ssa_lhs.get_identifier()); // aliasing may happen here value_setst::valuest expr_set; value_sets.get_values(target, dest.op0(), expr_set); hash_set_cont<irep_idt, irep_id_hash> symbols; for(value_setst::valuest::const_iterator it=expr_set.begin(); it!=expr_set.end(); it++) find_symbols(*it, symbols); if(symbols.find(lhs_identifier)!=symbols.end()) { // may alias! exprt tmp; tmp.swap(dest.op0()); dereference(target, tmp, ns, value_sets); dest.swap(tmp); compute_rec(dest); } else { // nah, ok compute_rec(dest.op0()); } } else Forall_operands(it, dest) compute_rec(*it); }
void goto_symext::process_array_expr_rec( exprt &expr, const typet &type) const { if(expr.id()==ID_if) { if_exprt &if_expr=to_if_expr(expr); process_array_expr_rec(if_expr.true_case(), type); process_array_expr_rec(if_expr.false_case(), type); } else if(expr.id()==ID_index) { // strip index index_exprt &index_expr=to_index_expr(expr); exprt tmp=index_expr.array(); expr.swap(tmp); } else if(expr.id()==ID_typecast) { // strip exprt tmp=to_typecast_expr(expr).op0(); expr.swap(tmp); process_array_expr_rec(expr, type); } else if(expr.id()==ID_address_of) { // strip exprt tmp=to_address_of_expr(expr).op0(); expr.swap(tmp); process_array_expr_rec(expr, type); } else if(expr.id()==ID_symbol && expr.get_bool(ID_C_SSA_symbol) && to_ssa_expr(expr).get_original_expr().id()==ID_index) { const ssa_exprt &ssa=to_ssa_expr(expr); const index_exprt &index_expr=to_index_expr(ssa.get_original_expr()); exprt tmp=index_expr.array(); expr.swap(tmp); } else Forall_operands(it, expr) process_array_expr_rec(*it, it->type()); if(!base_type_eq(expr.type(), type, ns)) { byte_extract_exprt be(byte_extract_id()); be.type()=type; be.op()=expr; be.offset()=gen_zero(index_type()); expr.swap(be); } }
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; }
void termination_baset::remove_ssa_ids(exprt &expr) const { if(expr.id()==ID_symbol) { irep_idt ident=expr.get(ID_identifier); ident = id2string(ident).substr(0, id2string(ident).rfind('@')); ident = id2string(ident).substr(0, id2string(ident).rfind('!')); expr.set(ID_identifier, ident); } Forall_operands(it, expr) remove_ssa_ids(*it); }
bool contains_if(exprt &dest, const namespacet &ns) { if(dest.id()==ID_if) return true; if(dest.has_operands()) Forall_operands(it, dest) if (contains_if(*it, ns)) return true; return false; }
void goto_symext::replace_nondet(exprt &expr) { if(expr.id()==ID_side_effect && expr.get(ID_statement)==ID_nondet) { exprt new_expr(ID_nondet_symbol, expr.type()); new_expr.set(ID_identifier, "symex::nondet"+std::to_string(nondet_count++)); new_expr.add_source_location()=expr.source_location(); expr.swap(new_expr); } else Forall_operands(it, expr) replace_nondet(*it); }
void goto_symext::process_array_expr(exprt &expr) { // This may change the type of the expression! if(expr.id()==ID_if) { if_exprt &if_expr=to_if_expr(expr); process_array_expr(if_expr.true_case()); process_array_expr_rec(if_expr.false_case(), if_expr.true_case().type()); if_expr.type()=if_expr.true_case().type(); } else if(expr.id()==ID_index) { // strip index index_exprt &index_expr=to_index_expr(expr); exprt tmp=index_expr.array(); expr.swap(tmp); } else if(expr.id()==ID_typecast) { // strip exprt tmp=to_typecast_expr(expr).op0(); expr.swap(tmp); process_array_expr(expr); } else if(expr.id()==ID_address_of) { // strip exprt tmp=to_address_of_expr(expr).op0(); expr.swap(tmp); process_array_expr(expr); } else if(expr.id()==ID_symbol && expr.get_bool(ID_C_SSA_symbol) && to_ssa_expr(expr).get_original_expr().id()==ID_index) { const ssa_exprt &ssa=to_ssa_expr(expr); const index_exprt &index_expr=to_index_expr(ssa.get_original_expr()); exprt tmp=index_expr.array(); expr.swap(tmp); } else Forall_operands(it, expr) process_array_expr(*it); }
void termination_baset::replace_nondet_sideeffects(exprt &expr) { if(expr.id()=="sideeffect" && expr.get("statement")=="nondet") { symbolt symbol; symbol.name=std::string("termination::nondet")+i2string(++nondet_counter); symbol.base_name=std::string("nondet")+i2string(nondet_counter); symbol.type=expr.type(); expr=symbol_expr(symbol); shadow_context.move(symbol); } else Forall_operands(it, expr) replace_nondet_sideeffects(*it); }
void namespace_baset::follow_macros(exprt &expr) const { if(expr.id()==ID_symbol) { const symbolt &symbol=lookup(expr); if(symbol.is_macro && !symbol.value.is_nil()) { expr=symbol.value; follow_macros(expr); } return; } Forall_operands(it, expr) follow_macros(*it); }
void subsitute_invariants_rec( const invariant_sett::invariantst &invariants, exprt &dest) { if((dest.id()==ID_and || dest.id()==ID_or || dest.id()==ID_not) && dest.type().id()==ID_bool) { Forall_operands(it, dest) subsitute_invariants_rec(invariants, *it); } else { #if 0 for(invariant_sett::invariantst::expr_sett::const_iterator it=invariants.expr_set().begin(); it!=invariants.expr_set().end(); it++) std::cout << "I: " << it->pretty() << std::endl; std::cout << "DEST: " << dest.pretty() << std::endl; #endif if(invariants.expr_set().find(dest)!= invariants.expr_set().end()) { dest.make_true(); } else { // inverted? exprt tmp(dest); tmp.make_not(); if(invariants.expr_set().find(tmp)!= invariants.expr_set().end()) { dest.make_false(); } } } }
static void adjust_pred_index(exprt& expr, const predicatest& all_preds, const predicatest& passive_preds) { Forall_operands(it, expr) adjust_pred_index(*it, all_preds, passive_preds); if(expr.id()==ID_predicate_symbol) { unsigned p=safe_str2unsigned(expr.get(ID_identifier).c_str()); if(p >= passive_preds.size()) { bool found=passive_preds.find(all_preds[p], p); assert(found); expr.id(ID_predicate_passive_symbol); expr.set(ID_identifier, p); } } }
void predicatest::make_expr_passive_rec( exprt& phi, const namespacet& ns, const unsigned subscript) { Forall_operands(it, phi) make_expr_passive_rec(*it, ns, subscript); if(phi.id()==ID_symbol) { symbol_exprt &phi_sym=to_symbol_expr(phi); const irep_idt &identifier=phi_sym.get_identifier(); assert(identifier.as_string().find('#')==std::string::npos); if(is_procedure_local(ns.lookup(identifier))) { std::ostringstream os; os << identifier << '#' << subscript; phi_sym.set_identifier(os.str()); } } }
void trans_wpt::wp_rec(exprt &expr) { Forall_operands(it, expr) wp_rec(*it); if(expr.id()==ID_symbol) { const irep_idt &identifier=expr.get(ID_identifier); const symbolt &symbol=ns.lookup(identifier); if(symbol.is_macro) { // it's just a macro expr=symbol.value; wp_rec(expr); } else if(symbol.is_statevar) { next_state_functionst::const_iterator it=next_state_functions.find(identifier); if(it==next_state_functions.end()) { throw "trans_wpt: no next state function for "+ id2string(identifier); } else { // replace! expr=it->second; } } else { // it's an input or so throw "trans_wpt: unexpected symbol: "+id2string(identifier); } } }
bool replace_symbolt::replace(exprt &dest) { if(dest.id()=="symbol") { expr_mapt::const_iterator it= expr_map.find(dest.identifier()); if(it!=expr_map.end()) { dest=it->second; return false; } } bool result=true; Forall_operands(it, dest) result=replace(*it) && result; result=replace(dest.type()) && result; return result; }
void c_typecheck_baset::typecheck_block(codet &code) { Forall_operands(it, code) typecheck_code(to_code(*it)); // do decl-blocks exprt new_ops; new_ops.operands().reserve(code.operands().size()); Forall_operands(it1, code) { if(it1->is_nil()) continue; codet &code_op=to_code(*it1); if(code_op.get_statement()==ID_label) { // these may be nested codet *code_ptr=&code_op; while(code_ptr->get_statement()==ID_label) { assert(code_ptr->operands().size()==1); code_ptr=&to_code(code_ptr->op0()); } //codet &label_op=*code_ptr; new_ops.move_to_operands(code_op); } else new_ops.move_to_operands(code_op); } code.operands().swap(new_ops.operands()); }
void local_SSAt::replace_side_effects_rec( exprt &expr, locationt loc, unsigned &counter) const { Forall_operands(it, expr) replace_side_effects_rec(*it, loc, counter); if(expr.id()==ID_side_effect) { const side_effect_exprt &side_effect_expr= to_side_effect_expr(expr); const irep_idt statement=side_effect_expr.get_statement(); if(statement==ID_nondet) { // turn into nondet_symbol exprt nondet_symbol(ID_nondet_symbol, expr.type()); counter++; const irep_idt identifier= "ssa::nondet"+ i2string(loc->location_number)+ "."+i2string(counter)+suffix; nondet_symbol.set(ID_identifier, identifier); expr.swap(nondet_symbol); } else if(statement==ID_malloc) { counter++; std::string tmp_suffix= i2string(loc->location_number)+ "."+i2string(counter)+suffix; expr=malloc_ssa(side_effect_expr, tmp_suffix, ns); } else throw "unexpected side effect: "+id2string(statement); } }
void goto_symext::replace_array_equal(exprt &expr) { if(expr.id()==ID_array_equal) { assert(expr.operands().size()==2); // we expect two index expressions process_array_expr(expr.op0()); process_array_expr(expr.op1()); // type checking if(ns.follow(expr.op0().type())!= ns.follow(expr.op1().type())) expr=false_exprt(); else { equal_exprt equality_expr(expr.op0(), expr.op1()); expr.swap(equality_expr); } } Forall_operands(it, expr) replace_array_equal(*it); }
exprt c_typecheck_baset::do_initializer_rec( const exprt &value, const typet &type, bool force_constant) { const typet &full_type=follow(type); if(full_type.id()==ID_incomplete_struct) { err_location(value); error() << "type `" << to_string(full_type) << "' is still incomplete -- cannot initialize" << eom; throw 0; } if(value.id()==ID_initializer_list) return do_initializer_list(value, type, force_constant); if(value.id()==ID_array && value.get_bool(ID_C_string_constant) && full_type.id()==ID_array && (full_type.subtype().id()==ID_signedbv || full_type.subtype().id()==ID_unsignedbv) && full_type.subtype().get(ID_width)==value.type().subtype().get(ID_width)) { exprt tmp=value; // adjust char type tmp.type().subtype()=full_type.subtype(); Forall_operands(it, tmp) it->type()=full_type.subtype(); if(full_type.id()==ID_array && to_array_type(full_type).is_complete()) { // check size mp_integer array_size; if(to_integer(to_array_type(full_type).size(), array_size)) { err_location(value); error() << "array size needs to be constant, got " << to_string(to_array_type(full_type).size()) << eom; throw 0; } if(array_size<0) { err_location(value); error() << "array size must not be negative" << eom; throw 0; } if(mp_integer(tmp.operands().size())>array_size) { // cut off long strings. gcc does a warning for this tmp.operands().resize(integer2size_t(array_size)); tmp.type()=type; } else if(mp_integer(tmp.operands().size())<array_size) { // fill up tmp.type()=type; exprt zero= zero_initializer( full_type.subtype(), value.source_location(), *this, get_message_handler()); tmp.operands().resize(integer2size_t(array_size), zero); } } return tmp; } if(value.id()==ID_string_constant && full_type.id()==ID_array && (full_type.subtype().id()==ID_signedbv || full_type.subtype().id()==ID_unsignedbv) && full_type.subtype().get(ID_width)==char_type().get(ID_width)) { // will go away, to be replaced by the above block string_constantt tmp1=to_string_constant(value); // adjust char type tmp1.type().subtype()=full_type.subtype(); exprt tmp2=tmp1.to_array_expr(); if(full_type.id()==ID_array && to_array_type(full_type).is_complete()) { // check size mp_integer array_size; if(to_integer(to_array_type(full_type).size(), array_size)) { err_location(value); error() << "array size needs to be constant, got " << to_string(to_array_type(full_type).size()) << eom; throw 0; } if(array_size<0) { err_location(value); error() << "array size must not be negative" << eom; throw 0; } if(mp_integer(tmp2.operands().size())>array_size) { // cut off long strings. gcc does a warning for this tmp2.operands().resize(integer2size_t(array_size)); tmp2.type()=type; } else if(mp_integer(tmp2.operands().size())<array_size) { // fill up tmp2.type()=type; exprt zero= zero_initializer( full_type.subtype(), value.source_location(), *this, get_message_handler()); tmp2.operands().resize(integer2size_t(array_size), zero); } } return tmp2; } if(full_type.id()==ID_array && to_array_type(full_type).size().is_nil()) { err_location(value); error() << "type `" << to_string(full_type) << "' cannot be initialized with `" << to_string(value) << "'" << eom; throw 0; } if(value.id()==ID_designated_initializer) { err_location(value); error() << "type `" << to_string(full_type) << "' cannot be initialized with designated initializer" << eom; throw 0; } exprt result=value; implicit_typecast(result, type); return result; }
void jsil_typecheckt::typecheck_expr_operands(exprt &expr) { Forall_operands(it, expr) typecheck_expr(*it); }
void jsil_typecheckt::typecheck_block(codet &code) { Forall_operands(it, code) typecheck_code(to_code(*it)); }