void havoc_loopst::get_modifies( const loopt &loop, modifiest &modifies) { for(loopt::const_iterator i_it=loop.begin(); i_it!=loop.end(); i_it++) { const goto_programt::instructiont &instruction=**i_it; if(instruction.is_assign()) { const exprt &lhs=to_code_assign(instruction.code).lhs(); function_modifies.get_modifies_lhs(local_may_alias, *i_it, lhs, modifies); } else if(instruction.is_function_call()) { const code_function_callt &code_function_call= to_code_function_call(instruction.code); const exprt &lhs=code_function_call.lhs(); // return value assignment if(lhs.is_not_nil()) function_modifies.get_modifies_lhs( local_may_alias, *i_it, lhs, modifies); function_modifies(code_function_call.function(), modifies); } } }
goto_programt::targett havoc_loopst::get_loop_exit(const loopt &loop) { assert(!loop.empty()); // find the last instruction in the loop std::map<unsigned, goto_programt::targett> loop_map; for(loopt::const_iterator l_it=loop.begin(); l_it!=loop.end(); l_it++) loop_map[(*l_it)->location_number]=*l_it; // get the one with the highest number goto_programt::targett last=(--loop_map.end())->second; return ++last; }
void havoc_loopst::havoc_loop( const goto_programt::targett loop_head, const loopt &loop) { assert(!loop.empty()); // first find out what can get changed in the loop modifiest modifies; get_modifies(loop, modifies); // build the havocking code goto_programt havoc_code; build_havoc_code(loop_head, modifies, havoc_code); // Now havoc at the loop head. Use insert_swap to // preserve jumps to loop head. goto_function.body.insert_before_swap(loop_head, havoc_code); // compute the loop exit goto_programt::targett loop_exit= get_loop_exit(loop); // divert all gotos to the loop head to the loop exit for(loopt::const_iterator l_it=loop.begin(); l_it!=loop.end(); l_it++) { goto_programt::instructiont &instruction=**l_it; if(instruction.is_goto()) { for(goto_programt::targetst::iterator t_it=instruction.targets.begin(); t_it!=instruction.targets.end(); t_it++) { if(*t_it==loop_head) *t_it=loop_exit; // divert } } } // remove skips remove_skip(goto_function.body); }
void k_inductiont::get_modifies( const loopt &loop, modifiest &modifies) { for(loopt::const_iterator i_it=loop.begin(); i_it!=loop.end(); i_it++) { const goto_programt::instructiont &instruction=**i_it; if(instruction.is_assign()) { const exprt &lhs=to_code_assign(instruction.code).lhs(); get_modifies_lhs(*i_it, lhs, modifies); } else if(instruction.is_function_call()) { const exprt &lhs=to_code_function_call(instruction.code).lhs(); get_modifies_lhs(*i_it, lhs, modifies); } } }