void goto_convertt::convert_CPROVER_throw( const codet &code, goto_programt &dest) { // set the 'exception' flag { goto_programt::targett t_set_exception= dest.add_instruction(ASSIGN); t_set_exception->source_location=code.source_location(); t_set_exception->code=code_assignt(exception_flag(), true_exprt()); } // do we catch locally? if(targets.throw_set) { // need to process destructor stack unwind_destructor_stack(code.source_location(), targets.throw_stack_size, dest); // add goto goto_programt::targett t=dest.add_instruction(); t->make_goto(targets.throw_target); t->source_location=code.source_location(); } else // otherwise, we do a return { // need to process destructor stack unwind_destructor_stack(code.source_location(), 0, dest); // add goto goto_programt::targett t=dest.add_instruction(); t->make_goto(targets.return_target); t->source_location=code.source_location(); } }
void goto_convertt::convert_CPROVER_try_catch( const codet &code, goto_programt &dest) { if(code.operands().size()!=2) { err_location(code); throw "CPROVER_try_catch expects two arguments"; } // this is where we go after 'throw' goto_programt tmp; tmp.add_instruction(SKIP)->source_location=code.source_location(); // set 'throw' target throw_targett throw_target(targets); targets.set_throw(tmp.instructions.begin()); // now put 'catch' code onto destructor stack code_ifthenelset catch_code; catch_code.cond()=exception_flag(); catch_code.add_source_location()=code.source_location(); catch_code.then_case()=to_code(code.op1()); targets.destructor_stack.push_back(catch_code); // now convert 'try' code convert(to_code(code.op0()), dest); // pop 'catch' code off stack targets.destructor_stack.pop_back(); // add 'throw' target dest.destructive_append(tmp); }