void goto_convertt::convert_msc_leave( const codet &code, goto_programt &dest) { if(!targets.leave_set) { error().source_location=code.find_source_location(); error() << "leave without target" << eom; throw 0; } // need to process destructor stack for(unsigned d=targets.destructor_stack.size(); d!=targets.leave_stack_size; d--) { codet d_code=targets.destructor_stack[d-1]; d_code.add_source_location()=code.source_location(); convert(d_code, dest); } goto_programt::targett t=dest.add_instruction(); t->make_goto(targets.leave_target); t->source_location=code.source_location(); }
void goto_convertt::convert_msc_try_except( const codet &code, goto_programt &dest) { if(code.operands().size()!=3) { error().source_location=code.find_source_location(); error() << "msc_try_except expects three arguments" << eom; throw 0; } convert(to_code(code.op0()), dest); // todo: generate exception tracking }
void goto_convertt::convert_CPROVER_try_finally( const codet &code, goto_programt &dest) { if(code.operands().size()!=2) { error().source_location=code.find_source_location(); error() << "CPROVER_try_finally expects two arguments" << eom; throw 0; } // first put 'finally' code onto destructor stack targets.destructor_stack.push_back(to_code(code.op1())); // do 'try' code convert(to_code(code.op0()), dest); // pop 'finally' from destructor stack targets.destructor_stack.pop_back(); // now add 'finally' code convert(to_code(code.op1()), dest); }
void goto_convertt::convert_msc_try_finally( const codet &code, goto_programt &dest) { if(code.operands().size()!=2) { error().source_location=code.find_source_location(); error() << "msc_try_finally expects two arguments" << eom; throw 0; } goto_programt tmp; tmp.add_instruction(SKIP)->source_location=code.source_location(); { // save 'leave' target leave_targett leave_target(targets); targets.set_leave(tmp.instructions.begin()); // first put 'finally' code onto destructor stack targets.destructor_stack.push_back(to_code(code.op1())); // do 'try' code convert(to_code(code.op0()), dest); // pop 'finally' from destructor stack targets.destructor_stack.pop_back(); // 'leave' target gets restored here } // now add 'finally' code convert(to_code(code.op1()), dest); // this is the target for 'leave' dest.destructive_append(tmp); }
void goto_convertt::convert_CPROVER_try_catch( const codet &code, goto_programt &dest) { if(code.operands().size()!=2) { error().source_location=code.find_source_location(); error() << "CPROVER_try_catch expects two arguments" << eom; throw 0; } // 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); }