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); }
DexMethod* MethodCreator::create() { if (method->is_concrete()) { method->set_code(std::move(to_code())); } else { method->make_concrete(access, std::move(to_code()), !(access & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR))); } return method; }
DexMethod* MethodCreator::create() { if (method->is_concrete()) { method->set_code(to_code()); } else { auto access = method->get_access(); bool is_virtual = !(access & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR)); method->make_concrete(access, to_code(), is_virtual); } return method; }
void jsil_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) { exprt &cond=code.cond(); typecheck_expr(cond); make_type_compatible(cond, bool_typet(), true); typecheck_code(to_code(code.then_case())); if(!code.else_case().is_nil()) typecheck_code(to_code(code.else_case())); }
void goto_convertt::convert_try_catch( const codet &code, goto_programt &dest) { assert(code.operands().size()>=2); // add the CATCH-push instruction to 'dest' goto_programt::targett catch_push_instruction=dest.add_instruction(); catch_push_instruction->make_catch(); catch_push_instruction->code.set_statement(ID_catch); catch_push_instruction->source_location=code.source_location(); // the CATCH-push instruction is annotated with a list of IDs, // one per target irept::subt &exception_list= catch_push_instruction->code.add(ID_exception_list).get_sub(); // add a SKIP target for the end of everything goto_programt end; goto_programt::targett end_target=end.add_instruction(); end_target->make_skip(); // the first operand is the 'try' block convert(to_code(code.op0()), dest); // add the CATCH-pop to the end of the 'try' block goto_programt::targett catch_pop_instruction=dest.add_instruction(); catch_pop_instruction->make_catch(); catch_pop_instruction->code.set_statement(ID_catch); // add a goto to the end of the 'try' block dest.add_instruction()->make_goto(end_target); for(unsigned i=1; i<code.operands().size(); i++) { const codet &block=to_code(code.operands()[i]); // grab the ID and add to CATCH instruction exception_list.push_back(irept(block.get(ID_exception_id))); goto_programt tmp; convert(block, tmp); catch_push_instruction->targets.push_back(tmp.instructions.begin()); dest.destructive_append(tmp); // add a goto to the end of the 'catch' block dest.add_instruction()->make_goto(end_target); } // add the end-target dest.destructive_append(end); }
void c_typecheck_baset::typecheck_ifthenelse(code_ifthenelset &code) { if(code.operands().size()!=3) { err_location(code); error() << "ifthenelse expected to have three operands" << eom; throw 0; } exprt &cond=code.cond(); typecheck_expr(cond); #if 0 if(cond.id()==ID_sideeffect && cond.get(ID_statement)==ID_assign) { warning("warning: assignment in if condition"); } #endif implicit_typecast_bool(cond); if(to_code(code.then_case()).get_statement()==ID_decl_block) { code_blockt code_block; code_block.add_source_location()=code.then_case().source_location(); code_block.move_to_operands(code.then_case()); code.then_case().swap(code_block); } typecheck_code(to_code(code.then_case())); if(!code.else_case().is_nil()) { if(to_code(code.else_case()).get_statement()==ID_decl_block) { code_blockt code_block; code_block.add_source_location()=code.else_case().source_location(); code_block.move_to_operands(code.else_case()); code.else_case().swap(code_block); } typecheck_code(to_code(code.else_case())); } }
void ansi_c_convertt::convert_declaration(ansi_c_declarationt &declaration) { c_storage_spect c_storage_spec; convert_type(declaration.type(), c_storage_spec); declaration.set_is_inline(c_storage_spec.is_inline); declaration.set_is_static(c_storage_spec.is_static); declaration.set_is_extern(c_storage_spec.is_extern); declaration.set_is_thread_local(c_storage_spec.is_thread_local); declaration.set_is_register(c_storage_spec.is_register); // do not overwrite is_typedef -- it's done by the parser // typedefs are macros if(declaration.get_is_typedef()) declaration.set_is_macro(true); if(declaration.value().is_not_nil()) { if(declaration.value().type().id()==ID_code) convert_code(to_code(declaration.value())); else convert_expr(declaration.value()); } }
void goto_convertt::cpp_new_initializer( const exprt &lhs, const side_effect_exprt &rhs, goto_programt &dest) { exprt initializer= static_cast<const exprt &>(rhs.find(ID_initializer)); if(initializer.is_not_nil()) { if(rhs.get_statement()=="cpp_new[]") { // build loop } else if(rhs.get_statement()==ID_cpp_new) { // just one object exprt deref_lhs(ID_dereference, rhs.type().subtype()); deref_lhs.copy_to_operands(lhs); replace_new_object(deref_lhs, initializer); convert(to_code(initializer), dest); } else assert(false); } }
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 jsil_typecheckt::typecheck_non_type_symbol(symbolt &symbol) { assert(!symbol.is_type); // Using is_extern to check if symbol was already typechecked if(symbol.is_extern) return; if(symbol.value.id()!="no-body-just-yet") symbol.is_extern=true; proc_name=symbol.name; typecheck_type(symbol.type); if(symbol.value.id()==ID_code) typecheck_code(to_code(symbol.value)); else if(symbol.name=="eval") { // No code for eval. Do nothing } else if(symbol.value.id()=="no-body-just-yet") { // Do nothing } else throw "Non type symbol value expected code, but got "+ symbol.value.pretty(); }
void goto_convertt::do_printf( const exprt &lhs, const exprt &function, const exprt::operandst &arguments, goto_programt &dest) { const irep_idt &f_id=function.get(ID_identifier); if(f_id==CPROVER_PREFIX "printf" || f_id=="printf") { typet return_type=static_cast<const typet &>(function.type().find(ID_return_type)); side_effect_exprt printf_code(ID_printf, return_type); printf_code.operands()=arguments; printf_code.add_source_location()=function.source_location(); if(lhs.is_not_nil()) { code_assignt assignment(lhs, printf_code); assignment.add_source_location()=function.source_location(); copy(assignment, ASSIGN, dest); } else { printf_code.id(ID_code); printf_code.type()=typet(ID_code); copy(to_code(printf_code), OTHER, dest); } } else assert(false); }
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 c_typecheck_baset::typecheck_start_thread(codet &code) { if(code.operands().size()!=1) { err_location(code); error() << "start_thread expected to have one operand" << eom; throw 0; } typecheck_code(to_code(code.op0())); }
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) { struct m5mols_info *info = to_m5mols(sd); if (enable) { if (info->code == to_code(M5MOLS_RES_MON)) { v4l2_info(sd, "%s : monitor mode\n", __func__); return m5mols_start_monitor(sd); } if (info->code == to_code(M5MOLS_RES_CAPTURE)) { v4l2_info(sd, "%s : capture mode\n", __func__); return m5mols_start_capture(sd); } return -EINVAL; } else { if (is_streaming(sd)) return m5mols_set_mode(sd, MODE_PARMSET); return -EINVAL; } }
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 goto_convertt::convert_CPROVER_try_finally( const codet &code, goto_programt &dest) { if(code.operands().size()!=2) { err_location(code); throw "CPROVER_try_finally expects two arguments"; } // 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_symext::symex_dead(statet &state) { const goto_programt::instructiont &instruction=*state.source.pc; const codet &code=to_code(instruction.code); if(code.operands().size()!=1) throw "dead expects one operand"; if(code.op0().id()!=ID_symbol) throw "dead expects symbol as first operand"; // We increase the L2 renaming to make these non-deterministic. // We also prevent propagation of old values. ssa_exprt ssa(to_symbol_expr(code.op0())); state.rename(ssa, ns, goto_symex_statet::L1); // in case of pointers, put something into the value set if(ns.follow(code.op0().type()).id()==ID_pointer) { exprt failed= get_failed_symbol(to_symbol_expr(code.op0()), ns); exprt rhs; if(failed.is_not_nil()) { address_of_exprt address_of_expr; address_of_expr.object()=failed; address_of_expr.type()=code.op0().type(); rhs=address_of_expr; } else rhs=exprt(ID_invalid); state.rename(rhs, ns, goto_symex_statet::L1); state.value_set.assign(ssa, rhs, ns, true, false); } ssa_exprt ssa_lhs=to_ssa_expr(ssa); const irep_idt &l1_identifier=ssa_lhs.get_identifier(); // prevent propagation state.propagation.remove(l1_identifier); // L2 renaming if(state.level2.current_names.find(l1_identifier)!= state.level2.current_names.end()) state.level2.increase_counter(l1_identifier); }
void goto_convertt::convert_msc_try_except( const codet &code, goto_programt &dest) { if(code.operands().size()!=3) { err_location(code); throw "msc_try_except expects three arguments"; } convert(to_code(code.op0()), dest); // todo: generate exception tracking }
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 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 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 }
bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler) { symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); // we need to zero out all static variables for(symbol_tablet::symbolst::const_iterator it=symbol_table.symbols.begin(); it!=symbol_table.symbols.end(); it++) { if(it->second.type.id()!=ID_code && it->second.is_lvalue && it->second.is_state_var && it->second.is_static_lifetime && it->second.value.is_not_nil() && it->second.mode==ID_java) { code_assignt assignment(it->second.symbol_expr(), it->second.value); code_block.add(assignment); } } // we now need to run all the <clinit> methods for(symbol_tablet::symbolst::const_iterator it=symbol_table.symbols.begin(); it!=symbol_table.symbols.end(); it++) { if(it->second.base_name=="<clinit>" && it->second.type.id()==ID_code && it->second.mode==ID_java) { code_function_callt function_call; function_call.lhs()=nil_exprt(); function_call.function()=it->second.symbol_expr(); code_block.add(function_call); } } return false; }
exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const { // get predecessor of "to" to--; if(to->is_end_function()) return static_cast<const exprt &>(get_nil_irep()); // must be the function call assert(to->is_function_call()); const code_function_callt &code= to_code_function_call(to_code(to->code)); return code.lhs(); }
void goto_symext::symex_decl(statet &state) { const goto_programt::instructiont &instruction=*state.source.pc; const codet &code=to_code(instruction.code); if(code.operands().size()==2) throw "two-operand decl not supported here"; if(code.operands().size()!=1) throw "decl expects one operand"; if(code.op0().id()!=ID_symbol) throw "decl expects symbol as first operand"; symex_decl(state, to_symbol_expr(code.op0())); }
void goto_convert( contextt &context, optionst &options, goto_programt &dest, message_handlert &message_handler) { // find main symbol const symbolst::const_iterator s_it= context.symbols.find("main"); if(s_it==context.symbols.end()) throw "failed to find main symbol"; const symbolt &symbol=s_it->second; std::cout << "goto_convert : start converting symbol table to goto functions " << std::endl; ::goto_convert(to_code(symbol.value), context, options, dest, message_handler); }
void c_typecheck_baset::typecheck_gcc_switch_case_range(codet &code) { if(code.operands().size()!=3) { err_location(code); error() << "gcc_switch_case_range expected to have three operands" << eom; throw 0; } typecheck_code(to_code(code.op2())); if(!case_is_allowed) { err_location(code); error() << "did not expect `case' here" << eom; throw 0; } typecheck_expr(code.op0()); typecheck_expr(code.op1()); implicit_typecast(code.op0(), switch_op_type); implicit_typecast(code.op1(), switch_op_type); }
void termination_baset::find_required_steps( const goto_tracet &goto_trace, goto_tracet::stepst::const_iterator &loop_begin, required_stepst &required_steps, const std::string &prefix) const { find_symbols_sett required_symbols; unsigned before=0, after=1; // initialize: find all (potential) loop exits and // remember the symbols in them for(goto_tracet::stepst::const_iterator it1=loop_begin; it1!=goto_trace.steps.end(); it1++) { if(it1->pc->is_goto() && it1->pc->function==loop_begin->pc->function) { bool found_next=false, found_target=false; goto_programt::const_targett next=it1->pc; next++; goto_programt::const_targett target=it1->pc->targets.front(); for(goto_tracet::stepst::const_iterator it2=loop_begin; it2!=goto_trace.steps.end(); it2++) { if(it1!=it2) { if(it2->pc==next) found_next=true; else if(it2->pc==target) found_target=true; } } if(!found_target || !found_next) { exprt temp=it1->cond_expr; remove_ssa_ids(temp); find_symbols(temp, required_symbols); } } } #if 0 std::cout << "INITIAL SYMBOLS: "; for(find_symbols_sett::const_iterator it=required_symbols.begin(); it!=required_symbols.end(); it++) std::cout << *it << ", "; std::cout << std::endl; #endif // get the fixpoint while(before!=after) { before=required_symbols.size(); for(goto_tracet::stepst::const_iterator step=loop_begin; step!=goto_trace.steps.end(); step++) { find_symbols_sett intersection; if(step->is_assignment()) { exprt lhs, rhs; const codet &code=to_code(step->pc->code); if(code.get_statement()==ID_assign) { const code_assignt &acode=to_code_assign(step->pc->code); lhs=acode.lhs(); rhs=acode.rhs(); } else if(code.get_statement()==ID_function_call) { const code_function_callt fcode=to_code_function_call(step->pc->code); lhs=fcode.lhs(); rhs=fcode.op2(); } else throw "Unexpected assign statement"; if(lhs.id()==ID_symbol && has_prefix(lhs.get_string(ID_identifier), prefix)) { // if we depend on the RHS syms, we also need the pre-symbol find_symbols_sett rhs_sym; find_symbols(rhs, rhs_sym); if(intersects(rhs_sym, required_symbols)) { find_symbols(lhs, required_symbols); required_steps.insert(&(*step)); } } else { find_symbols_sett lhs_sym; if(lhs.id()==ID_index) find_symbols(lhs.op0(), lhs_sym); // we're not modifying the index else find_symbols(lhs, lhs_sym); if(intersects(lhs_sym, required_symbols)) { find_symbols(rhs, required_symbols); required_steps.insert(&(*step)); } } } else if(step->is_assume()) { find_symbols_sett syms; find_symbols(step->pc->guard, syms); if(intersects(syms, required_symbols)) { required_symbols.insert(syms.begin(), syms.end()); required_steps.insert(&(*step)); } } } after=required_symbols.size(); #if 0 std::cout << "REQUIRED SYMBOLS: "; for(find_symbols_sett::const_iterator it=required_symbols.begin(); it!=required_symbols.end(); it++) std::cout << *it << ", "; std::cout << std::endl; #endif } }
bool static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler) { namespacet ns(symbol_table); symbol_tablet::symbolst::iterator s_it= symbol_table.symbols.find(INITIALIZE_FUNCTION); if(s_it==symbol_table.symbols.end()) return false; symbolt &init_symbol=s_it->second; init_symbol.value=code_blockt(); init_symbol.value.add_source_location()=source_location; code_blockt &dest=to_code_block(to_code(init_symbol.value)); // add the magic label to hide dest.add(code_labelt("__CPROVER_HIDE", code_skipt())); // do assignments based on "value" // sort alphabetically for reproducible results std::set<std::string> symbols; forall_symbols(it, symbol_table.symbols) symbols.insert(id2string(it->first)); for(const std::string &id : symbols) { const symbolt &symbol=ns.lookup(id); const irep_idt &identifier=symbol.name; if(!symbol.is_static_lifetime) continue; if(symbol.is_type || symbol.is_macro) continue; // special values if(identifier==CPROVER_PREFIX "constant_infinity_uint" || identifier==CPROVER_PREFIX "memory" || identifier=="__func__" || identifier=="__FUNCTION__" || identifier=="__PRETTY_FUNCTION__" || identifier=="argc'" || identifier=="argv'" || identifier=="envp'" || identifier=="envp_size'") continue; // just for linking if(has_prefix(id, CPROVER_PREFIX "architecture_")) continue; const typet &type=ns.follow(symbol.type); // check type if(type.id()==ID_code || type.id()==ID_empty) continue; // We won't try to initialize any symbols that have // remained incomplete. if(symbol.value.is_nil() && symbol.is_extern) // Compilers would usually complain about these // symbols being undefined. continue; if(type.id()==ID_array && to_array_type(type).size().is_nil()) { // C standard 6.9.2, paragraph 5 // adjust the type to an array of size 1 symbol_tablet::symbolst::iterator it= symbol_table.symbols.find(identifier); assert(it!=symbol_table.symbols.end()); it->second.type=type; it->second.type.set(ID_size, from_integer(1, size_type())); } if(type.id()==ID_incomplete_struct || type.id()==ID_incomplete_union) continue; // do not initialize if(symbol.value.id()==ID_nondet) continue; // do not initialize exprt rhs; if(symbol.value.is_nil()) { try { namespacet ns(symbol_table); rhs=zero_initializer(symbol.type, symbol.location, ns, message_handler); assert(rhs.is_not_nil()); } catch(...) { return true; } } else rhs=symbol.value; code_assignt code(symbol.symbol_expr(), rhs); code.add_source_location()=symbol.location; dest.move_to_operands(code); } // call designated "initialization" functions for(const std::string &id : symbols) { const symbolt &symbol=ns.lookup(id); if(symbol.type.id()==ID_code && to_code_type(symbol.type).return_type().id()==ID_constructor) { code_function_callt function_call; function_call.function()=symbol.symbol_expr(); function_call.add_source_location()=source_location; dest.move_to_operands(function_call); } } return false; }
void c_typecheck_baset::typecheck_function_body(symbolt &symbol) { code_typet &code_type=to_code_type(symbol.type); assert(symbol.value.is_not_nil()); // reset labels labels_used.clear(); labels_defined.clear(); // fix type symbol.value.type()=code_type; // set return type return_type=code_type.return_type(); unsigned anon_counter=0; // Add the parameter declarations into the symbol table. code_typet::parameterst ¶meters=code_type.parameters(); for(code_typet::parameterst::iterator p_it=parameters.begin(); p_it!=parameters.end(); p_it++) { // may be anonymous if(p_it->get_base_name()==irep_idt()) { irep_idt base_name="#anon"+i2string(anon_counter++); p_it->set_base_name(base_name); } // produce identifier irep_idt base_name=p_it->get_base_name(); irep_idt identifier=id2string(symbol.name)+"::"+id2string(base_name); p_it->set_identifier(identifier); parameter_symbolt p_symbol; p_symbol.type=p_it->type(); p_symbol.name=identifier; p_symbol.base_name=base_name; p_symbol.location=p_it->source_location(); symbolt *new_p_symbol; move_symbol(p_symbol, new_p_symbol); } // typecheck the body code typecheck_code(to_code(symbol.value)); // special case for main() if(symbol.name==ID_main) add_argc_argv(symbol); // check the labels for(std::map<irep_idt, source_locationt>::const_iterator it=labels_used.begin(); it!=labels_used.end(); it++) { if(labels_defined.find(it->first)==labels_defined.end()) { err_location(it->second); str << "branching label `" << it->first << "' is not defined in function"; throw 0; } } }
void jsil_typecheckt::typecheck_block(codet &code) { Forall_operands(it, code) typecheck_code(to_code(*it)); }