void concurrency_instrumentationt::instrument( goto_programt &goto_program, const is_threadedt &is_threaded) { for(goto_programt::instructionst::iterator it=goto_program.instructions.begin(); it!=goto_program.instructions.end(); it++) { if(it->is_assign()) { code_assignt &code=to_code_assign(it->code); instrument(code.rhs()); } else if(it->is_assume() || it->is_assert() || it->is_goto()) instrument(it->guard); else if(it->is_function_call()) { code_function_callt &code=to_code_function_call(it->code); instrument(code.function()); //instrument(code.lhs(), LHS); Forall_expr(it, code.arguments()) instrument(*it); } } }
void goto_convertt::do_function_call( const exprt &lhs, const exprt &function, const exprt::operandst &arguments, goto_programt &dest) { // make it all side effect free exprt new_lhs=lhs, new_function=function; exprt::operandst new_arguments=arguments; if(!new_lhs.is_nil()) clean_expr(new_lhs, dest); clean_expr(new_function, dest); // the arguments of __noop do not get evaluated if(new_function.id()==ID_symbol && to_symbol_expr(new_function).get_identifier()=="__noop") { new_arguments.clear(); } Forall_expr(it, new_arguments) clean_expr(*it, dest); // split on the function if(new_function.id()==ID_if) { do_function_call_if(new_lhs, to_if_expr(new_function), new_arguments, dest); } else if(new_function.id()==ID_symbol) { do_function_call_symbol(new_lhs, to_symbol_expr(new_function), new_arguments, dest); } else if(new_function.id()=="NULL-object") { } else if(new_function.id()==ID_dereference || new_function.id()=="virtual_function") { do_function_call_other(new_lhs, new_function, new_arguments, dest); } else { error().source_location=function.find_source_location(); error() << "unexpected function argument: " << new_function.id() << eom; throw 0; } }
void goto_symext::symex_step( const goto_functionst &goto_functions, statet &state) { #if 0 std::cout << "\ninstruction type is " << state.source.pc->type << '\n'; std::cout << "Location: " << state.source.pc->source_location << '\n'; std::cout << "Guard: " << from_expr(ns, "", state.guard.as_expr()) << '\n'; std::cout << "Code: " << from_expr(ns, "", state.source.pc->code) << '\n'; #endif assert(!state.threads.empty()); assert(!state.call_stack().empty()); const goto_programt::instructiont &instruction=*state.source.pc; merge_gotos(state); // depth exceeded? { unsigned max_depth=options.get_unsigned_int_option("depth"); if(max_depth!=0 && state.depth>max_depth) state.guard.add(false_exprt()); state.depth++; } // actually do instruction switch(instruction.type) { case SKIP: if(!state.guard.is_false()) target.location(state.guard.as_expr(), state.source); state.source.pc++; break; case END_FUNCTION: // do even if state.guard.is_false() to clear out frame created // in symex_start_thread symex_end_of_function(state); state.source.pc++; break; case LOCATION: if(!state.guard.is_false()) target.location(state.guard.as_expr(), state.source); state.source.pc++; break; case GOTO: symex_goto(state); break; case ASSUME: if(!state.guard.is_false()) { exprt tmp=instruction.guard; clean_expr(tmp, state, false); state.rename(tmp, ns); symex_assume(state, tmp); } state.source.pc++; break; case ASSERT: if(!state.guard.is_false()) { std::string msg=id2string(state.source.pc->source_location.get_comment()); if(msg=="") msg="assertion"; exprt tmp(instruction.guard); clean_expr(tmp, state, false); vcc(tmp, msg, state); } state.source.pc++; break; case RETURN: if(!state.guard.is_false()) return_assignment(state); state.source.pc++; break; case ASSIGN: if(!state.guard.is_false()) symex_assign_rec(state, to_code_assign(instruction.code)); state.source.pc++; break; case FUNCTION_CALL: if(!state.guard.is_false()) { code_function_callt deref_code= to_code_function_call(instruction.code); if(deref_code.lhs().is_not_nil()) clean_expr(deref_code.lhs(), state, true); clean_expr(deref_code.function(), state, false); Forall_expr(it, deref_code.arguments()) clean_expr(*it, state, false); symex_function_call(goto_functions, state, deref_code); } else state.source.pc++; break; case OTHER: if(!state.guard.is_false()) symex_other(goto_functions, state); state.source.pc++; break; case DECL: if(!state.guard.is_false()) symex_decl(state); state.source.pc++; break; case DEAD: symex_dead(state); state.source.pc++; break; case START_THREAD: symex_start_thread(state); state.source.pc++; break; case END_THREAD: // behaves like assume(0); if(!state.guard.is_false()) state.guard.add(false_exprt()); state.source.pc++; break; case ATOMIC_BEGIN: symex_atomic_begin(state); state.source.pc++; break; case ATOMIC_END: symex_atomic_end(state); state.source.pc++; break; case CATCH: symex_catch(state); state.source.pc++; break; case THROW: symex_throw(state); state.source.pc++; break; case NO_INSTRUCTION_TYPE: throw "symex got NO_INSTRUCTION"; default: throw "symex got unexpected instruction"; } }