void java_record_outputs( const symbolt &function, const exprt::operandst &main_arguments, code_blockt &init_code, symbol_tablet &symbol_table) { const code_typet::parameterst ¶meters= to_code_type(function.type).parameters(); exprt::operandst result; result.reserve(parameters.size()+1); bool has_return_value= to_code_type(function.type).return_type()!=empty_typet(); if(has_return_value) { // record return value codet output(ID_output); output.operands().resize(2); const symbolt &return_symbol=symbol_table.lookup("return'"); output.op0()= address_of_exprt( index_exprt( string_constantt(return_symbol.base_name), from_integer(0, index_type()))); output.op1()=return_symbol.symbol_expr(); output.add_source_location()=function.location; init_code.move_to_operands(output); } for(std::size_t param_number=0; param_number<parameters.size(); param_number++) { const symbolt &p_symbol= symbol_table.lookup(parameters[param_number].get_identifier()); if(p_symbol.type.id()==ID_pointer) { // record as an output codet output(ID_output); output.operands().resize(2); output.op0()= address_of_exprt( index_exprt( string_constantt(p_symbol.base_name), from_integer(0, index_type()))); output.op1()=main_arguments[param_number]; output.add_source_location()=function.location; init_code.move_to_operands(output); } } }
/// Remove the body of function "identifier" such that an analysis will treat it /// as a side-effect free function with non-deterministic return value. /// \par parameters: symbol_table Input symbol table to be modified /// goto_functions Input functions to be modified /// identifier Function to be removed /// message_handler Error/status output void remove_function( symbol_tablet &symbol_table, goto_functionst &goto_functions, const irep_idt &identifier, message_handlert &message_handler) { messaget message(message_handler); goto_functionst::function_mapt::iterator entry= goto_functions.function_map.find(identifier); if(entry==goto_functions.function_map.end()) { message.error() << "No function " << identifier << " in goto program" << messaget::eom; return; } else if(entry->second.is_inlined()) { message.warning() << "Function " << identifier << " is inlined, " << "instantiations will not be removed" << messaget::eom; } if(entry->second.body_available()) { message.status() << "Removing body of " << identifier << messaget::eom; entry->second.clear(); symbol_table.lookup(identifier).value.make_nil(); } }
std::string get_prog_var_name(const symbol_tablet &st, const goto_programt::targett &decl) { const irep_idt &base_id=st.lookup(get_affected_variable(*decl)).base_name; std::string base_name(id2string(base_id)); return base_name+=PROG_SUFFIX; }
goto_programt::targett cegis_assign_user_variable(const symbol_tablet &st, goto_functionst &gf, const goto_programt::targett &insert_after_pos, const irep_idt &name, const exprt &value) { const symbol_exprt lhs(st.lookup(name).symbol_expr()); return cegis_assign(st, gf, insert_after_pos, lhs, value); }
goto_programt::targett assign_jsa_meta_variable(const symbol_tablet &st, goto_functionst &gf, const goto_programt::targett &pos, const std::string &base_name, const exprt &expr_value) { const std::string name(get_cegis_meta_name(base_name)); const symbol_exprt lhs(st.lookup(name).symbol_expr()); return jsa_assign(st, gf, pos, lhs, expr_value); }
dereference_exprt cegis_operand(const symbol_tablet &st, const std::string &func_name, const typet &type, const size_t op) { const member_exprt operand_id(cegis_operand_id(st, func_name, op)); const std::string array_name(cegis_operand_array_name(st, type)); const symbol_exprt array(st.lookup(array_name).symbol_expr()); return dereference_exprt(index_exprt(array, operand_id), type); }
void execute_inv_prog(const symbol_tablet &st, goto_functionst &gf, const size_t max_solution_size, const goto_programt::targett &decl, const std::string &prog_base_name) { goto_programt &body=get_entry_body(gf); goto_programt::targett pos=decl; goto_programt::targett execution=body.insert_after(++pos); execution->type=goto_program_instruction_typet::FUNCTION_CALL; execution->source_location=default_cegis_source_location(); code_function_callt call; call.function()=st.lookup(DANGER_EXECUTE).symbol_expr(); const std::string prog_name(get_cegis_meta_name(prog_base_name)); const symbol_exprt prog_symbol(st.lookup(prog_name).symbol_expr()); const typet size_type(unsigned_int_type()); const constant_exprt index(from_integer(0u, size_type)); const index_exprt first_elem(prog_symbol, index); call.arguments().push_back(address_of_exprt(first_elem)); const constant_exprt size(from_integer(max_solution_size, size_type)); call.arguments().push_back(size); execution->code=call; }
goto_programt::targett cegis_assign_local_variable(const symbol_tablet &st, goto_programt &body, const goto_programt::targett &insert_after_pos, const std::string &func_name, const std::string &var_name, const exprt &value) { std::string name(func_name); name+=NS_SEP; name+=var_name; const symbol_exprt lhs(st.lookup(name).symbol_expr()); const source_locationt loc(default_cegis_source_location()); return cegis_assign(st, body, insert_after_pos, lhs, value, loc); }
void propagate_controller_sizes(const symbol_tablet &st, goto_functionst &gf) { const symbolt &symbol=st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME); const struct_exprt &controller_value=to_struct_expr(symbol.value); const namespacet ns(st); const exprt &a_size=get_a_size(ns, controller_value); const exprt &b_size=get_b_size(ns, controller_value); replace_sizes_visitort visitor(a_size, b_size); goto_programt &body=get_entry_body(gf); for (goto_programt::instructiont &instr : body.instructions) { instr.code.visit(visitor); instr.guard.visit(visitor); } }
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; }
size_t get_size(const symbol_tablet &st, const char * const id) { return to_size(to_array_type(st.lookup(id).type).size()); }
bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler, bool assume_init_pointers_not_null, unsigned max_nondet_array_length) { 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, or nondet-initialize if they're // external. Iterate over a copy of the symtab, as its iterators are // invalidated by object_factory: std::list<irep_idt> symbol_names; for(const auto &entry : symbol_table.symbols) symbol_names.push_back(entry.first); for(const auto &symname : symbol_names) { const symbolt &sym=symbol_table.lookup(symname); if(should_init_symbol(sym)) { if(sym.value.is_nil() && sym.type!=empty_typet()) { bool allow_null=!assume_init_pointers_not_null; if(allow_null) { std::string namestr=id2string(sym.symbol_expr().get_identifier()); const std::string suffix="@class_model"; // Static '.class' fields are always non-null. if(has_suffix(namestr, suffix)) allow_null=false; if(allow_null && has_prefix( namestr, "java::java.lang.String.Literal")) allow_null=false; } auto newsym=object_factory( sym.type, code_block, allow_null, symbol_table, max_nondet_array_length, source_location, message_handler); code_assignt assignment(sym.symbol_expr(), newsym); code_block.add(assignment); } else if(sym.value.is_not_nil()) { code_assignt assignment(sym.symbol_expr(), sym.value); assignment.add_source_location()=source_location; 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(); function_call.add_source_location()=source_location; code_block.add(function_call); } } return false; }
exprt::operandst java_build_arguments( const symbolt &function, code_blockt &init_code, symbol_tablet &symbol_table, bool assume_init_pointers_not_null, unsigned max_nondet_array_length, message_handlert &message_handler) { const code_typet::parameterst ¶meters= to_code_type(function.type).parameters(); exprt::operandst main_arguments; main_arguments.resize(parameters.size()); for(std::size_t param_number=0; param_number<parameters.size(); param_number++) { bool is_this=(param_number==0) && parameters[param_number].get_this(); bool is_default_entry_point(config.main.empty()); bool is_main=is_default_entry_point; if(!is_main) { bool named_main=has_suffix(config.main, ".main"); const typet &string_array_type= java_type_from_string("[Ljava.lang.String;"); bool has_correct_type= to_code_type(function.type).return_type().id()==ID_empty && (!to_code_type(function.type).has_this()) && parameters.size()==1 && parameters[0].type().full_eq(string_array_type); is_main=(named_main && has_correct_type); } bool allow_null=(!is_main) && (!is_this) && !assume_init_pointers_not_null; main_arguments[param_number]= object_factory( parameters[param_number].type(), init_code, allow_null, symbol_table, max_nondet_array_length, function.location, message_handler); const symbolt &p_symbol= symbol_table.lookup(parameters[param_number].get_identifier()); // record as an input codet input(ID_input); input.operands().resize(2); input.op0()= address_of_exprt( index_exprt( string_constantt(p_symbol.base_name), from_integer(0, index_type()))); input.op1()=main_arguments[param_number]; input.add_source_location()=function.location; init_code.move_to_operands(input); } return main_arguments; }