static void build_ssa_identifier_rec( const exprt &expr, const irep_idt &l0, const irep_idt &l1, const irep_idt &l2, std::ostream &os, std::ostream &l1_object_os) { if(expr.id()==ID_member) { const member_exprt &member=to_member_expr(expr); build_ssa_identifier_rec(member.struct_op(), l0, l1, l2, os, l1_object_os); os << '.' << member.get_component_name(); } else if(expr.id()==ID_index) { const index_exprt &index=to_index_expr(expr); build_ssa_identifier_rec(index.array(), l0, l1, l2, os, l1_object_os); mp_integer idx; if(to_integer(to_constant_expr(index.index()), idx)) assert(false); os << '[' << idx << ']'; } else if(expr.id()==ID_symbol) { auto symid=to_symbol_expr(expr).get_identifier(); os << symid; l1_object_os << symid; if(!l0.empty()) { os << '!' << l0; l1_object_os << '!' << l0; } if(!l1.empty()) { os << '@' << l1; l1_object_os << '@' << l1; } if(!l2.empty()) os << '#' << l2; } else assert(false); }
void gcc_message_handlert::print( unsigned level, const std::string &message, int sequence_number, const source_locationt &location) { const irep_idt file=location.get_file(); const irep_idt line=location.get_line(); const irep_idt column=location.get_column(); const irep_idt function=location.get_function(); std::string dest; if(!function.empty()) { if(!file.empty()) dest+=id2string(file)+":"; if(dest!="") dest+=' '; dest+="In function '"+id2string(function)+"':\n"; } if(!line.empty()) { if(!file.empty()) dest+=id2string(file)+":"; dest+=id2string(line)+":"; if(column.empty()) dest+="1: "; else dest+=id2string(column)+": "; if(level==message_clientt::M_ERROR) dest+="error: "; else if(level==message_clientt::M_WARNING) dest+="warning: "; } dest+=message; print(level, dest); }
void print_file(const datat &data, irep_idt file, std::ostream &out) { out << "<div class=\"file\" onclick=\"location.href='" << html_escape(id2string(file)+".html") << "';\" style=\"cursor:pointer;\">\n"; out << "<div class=\"filename\">" << html_escape(file) << "</div>\n"; out << "<div class=\"listing\">\n"; std::ifstream in(file.c_str()); if(!in) { } else { // line to property number std::map<unsigned, std::vector<unsigned> > line_map; for(datat::propertiest::const_iterator e_it=data.properties.begin(); e_it!=data.properties.end(); e_it++) if(e_it->file==file) { line_map[e_it->line].push_back(e_it-data.properties.begin()); } syntax_highlightingt syntax_highlighting(out); unsigned line_no=1; std::string line; while(std::getline(in, line)) { syntax_highlighting.strong_class=""; syntax_highlighting.line_no=line_no; std::vector<unsigned> &properties=line_map[line_no]; if(!properties.empty()) { syntax_highlighting.strong_class="alarm"; } syntax_highlighting(line); line_no++; } } out << "</div></div>\n\n"; }
void remove_virtual_functionst::get_functions( const exprt &function, functionst &functions) { const irep_idt class_id=function.get(ID_C_class); const irep_idt component_name=function.get(ID_component_name); assert(!class_id.empty()); functiont root_function; // Start from current class, go to parents until something // is found. irep_idt c=class_id; while(!c.empty()) { exprt method=get_method(c, component_name); if(method.is_not_nil()) { root_function.class_id=c; root_function.symbol_expr=to_symbol_expr(method); root_function.symbol_expr.set(ID_C_class, c); break; // abort } const class_hierarchyt::idst &parents= class_hierarchy.class_map[c].parents; if(parents.empty()) break; c=parents.front(); } if(root_function.class_id.empty()) { // No definition here; this is an abstract function. root_function.class_id=class_id; } // iterate over all children, transitively std::set<irep_idt> visited; get_child_functions_rec( class_id, root_function.symbol_expr, component_name, functions, visited); if(root_function.symbol_expr!=symbol_exprt()) functions.push_back(root_function); }
void remove_virtual_functionst::get_functions( const exprt &function, functionst &functions) { const irep_idt class_id=function.get(ID_C_class); const irep_idt component_name=function.get(ID_component_name); assert(!class_id.empty()); // iterate over all children, transitively std::vector<irep_idt> children= class_hierarchy.get_children_trans(class_id); for(const auto & child : children) { exprt method=get_method(child, component_name); if(method.is_not_nil()) { functiont function; function.class_id=child; function.symbol_expr=to_symbol_expr(method); function.symbol_expr.set(ID_C_class, child); functions.push_back(function); } } // Start from current class, go to parents until something // is found. irep_idt c=class_id; while(!c.empty()) { exprt method=get_method(c, component_name); if(method.is_not_nil()) { functiont function; function.class_id=c; function.symbol_expr=to_symbol_expr(method); function.symbol_expr.set(ID_C_class, c); functions.push_back(function); break; // abort } const class_hierarchyt::idst &parents= class_hierarchy.class_map[c].parents; if(parents.empty()) break; c=parents.front(); } }
bool java_entry_point( symbol_tablet &symbol_table, const irep_idt &main_class, message_handlert &message_handler) { // check if the entry point is already there if(symbol_table.symbols.find(goto_functionst::entry_point())!= symbol_table.symbols.end()) return false; // silently ignore messaget message(message_handler); symbolt symbol; // main function symbol // find main symbol if(config.main!="") { // Add java:: prefix std::string main_identifier="java::"+config.main; symbol_tablet::symbolst::const_iterator s_it; // Does it have a type signature? (':' suffix) if(config.main.rfind(':')==std::string::npos) { std::string prefix=main_identifier+':'; std::set<irep_idt> matches; for(const auto & s : symbol_table.symbols) if(has_prefix(id2string(s.first), prefix) && s.second.type.id()==ID_code) matches.insert(s.first); if(matches.empty()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; return true; } else if(matches.size()==1) { s_it=symbol_table.symbols.find(*matches.begin()); assert(s_it!=symbol_table.symbols.end()); } else { message.error() << "main symbol `" << config.main << "' is ambiguous:\n"; for(const auto & s : matches) message.error() << " " << s << '\n'; message.error() << messaget::eom; return true; } } else { // just look it up s_it=symbol_table.symbols.find(main_identifier); if(s_it==symbol_table.symbols.end()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; return true; } } // function symbol symbol=s_it->second; if(symbol.type.id()!=ID_code) { message.error() << "main symbol `" << config.main << "' not a function" << messaget::eom; return true; } // check if it has a body if(symbol.value.is_nil()) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; return true; } } else { // no function given, we look for the main class assert(config.main==""); // are we given a main class? if(main_class.empty()) return false; // silently ignore std::string entry_method= id2string(main_class)+".main"; std::string prefix="java::"+entry_method+":"; // look it up std::set<irep_idt> matches; for(symbol_tablet::symbolst::const_iterator s_it=symbol_table.symbols.begin(); s_it!=symbol_table.symbols.end(); s_it++) { if(s_it->second.type.id()==ID_code && has_prefix(id2string(s_it->first), prefix)) matches.insert(s_it->first); } if(matches.empty()) { // Not found, silently ignore return false; } if(matches.size()>=2) { message.error() << "main method in `" << main_class << "' is ambiguous" << messaget::eom; return true; // give up with error, no main } // function symbol symbol=symbol_table.symbols.find(*matches.begin())->second; // check if it has a body if(symbol.value.is_nil()) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; return true; // give up with error } } assert(!symbol.value.is_nil()); assert(symbol.type.id()==ID_code); const code_typet &code_type=to_code_type(symbol.type); create_initialize(symbol_table); if(java_static_lifetime_init(symbol_table, symbol.location, message_handler)) return true; code_blockt init_code; // build call to initialization function { symbol_tablet::symbolst::iterator init_it= symbol_table.symbols.find(INITIALIZE); if(init_it==symbol_table.symbols.end()) { message.error() << "failed to find " INITIALIZE " symbol" << messaget::eom; return true; // give up with error } code_function_callt call_init; call_init.lhs().make_nil(); call_init.add_source_location()=symbol.location; call_init.function()=init_it->second.symbol_expr(); init_code.move_to_operands(call_init); } // build call to the main method code_function_callt call_main; call_main.add_source_location()=symbol.location; call_main.function()=symbol.symbol_expr(); const code_typet::parameterst ¶meters= code_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 allow_null=config.main!="" && !is_this; main_arguments[param_number]= object_factory(parameters[param_number].type(), init_code, allow_null, symbol_table); } call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); // add "main" symbolt new_symbol; code_typet main_type; main_type.return_type()=empty_typet(); new_symbol.name=goto_functionst::entry_point(); new_symbol.type.swap(main_type); new_symbol.value.swap(init_code); new_symbol.mode=ID_java; if(symbol_table.move(new_symbol)) { message.error() << "failed to move main symbol" << messaget::eom; return true; } return false; }
void string_constantt::set_value(const irep_idt &value) { exprt size_expr=from_integer(value.size()+1, int_type()); type().add(ID_size).swap(size_expr); set(ID_value, value); }
void modelcheckert::inlinedt::build( abstract_modelt &abstract_model, const irep_idt f_id, std::set<irep_idt> &recursion_stack) { abstract_functionst::function_mapt::iterator f_it= abstract_model.goto_functions.function_map.find(f_id); if(f_it==abstract_model.goto_functions.function_map.end()) return; if(recursion_stack.find(f_id)!=recursion_stack.end()) { message.warning("Ignoring recursive call to `" + f_id.as_string() + "'."); return; } else recursion_stack.insert(f_id); abstract_programt &abstract_program=f_it->second.body; // first build target map // and do inlining typedef std::map<abstract_programt::const_targett, unsigned> target_mapt; target_mapt target_map; PC_map.reserve(PC_map.size()+abstract_program.instructions.size()); unsigned last_PC; for(abstract_programt::instructionst::iterator i_it=abstract_program.instructions.begin(); i_it!=abstract_program.instructions.end(); i_it++) { unsigned PC=PC_map.size(); PC_map.push_back(instructiont()); instructiont &instruction=PC_map.back(); instruction.original=i_it; target_map[i_it]=PC; last_PC=PC; // do function calls if(i_it->is_function_call()) { // figure out what is called const code_function_callt &call= to_code_function_call(i_it->code.concrete_pc->code); if(call.function().id()!="symbol") throw "expected symbol as function argument"; const symbol_exprt &symbol=to_symbol_expr(call.function()); build(abstract_model, symbol.get_identifier(), recursion_stack); } } // 2nd run: do targets for(abstract_programt::instructionst::iterator i_it=abstract_program.instructions.begin(); i_it!=abstract_program.instructions.end(); i_it++) { unsigned PC=target_map[i_it]; if(i_it->is_return()) // jump to end of function { PC_map[PC].targets.push_back(last_PC); } else { const abstract_programt::targetst &targets=i_it->targets; for(abstract_programt::targetst::const_iterator t_it=targets.begin(); t_it!=targets.end(); t_it++) { target_mapt::const_iterator m_it=target_map.find(*t_it); if(m_it==target_map.end()) throw "failed to find target"; PC_map[PC].targets.push_back(m_it->second); } } } recursion_stack.erase(f_id); }
index2tc valid_index_expr(get_bool_type(), valid_sym, ptr_obj); expr2tc falsity = gen_false_expr(); symex_assign(code_assign2tc(valid_index_expr, falsity), true); } void goto_symext::symex_printf( const expr2tc &lhs __attribute__((unused)), const expr2tc &rhs) { assert(is_code_printf2t(rhs)); code_printf2tc new_rhs(to_code_printf2t(rhs)); cur_state->rename(new_rhs); // The expr2tc in position 0 is the string format const irep_idt fmt = get_string_argument(new_rhs->operands[0]); // Now we pop the format new_rhs->operands.erase(new_rhs->operands.begin()); std::list<expr2tc> args; new_rhs->foreach_operand([this, &args](const expr2tc &e) { expr2tc tmp = e; do_simplify(tmp); args.push_back(tmp); }); target->output( cur_state->guard.as_expr(), cur_state->source, fmt.as_string(), args); }
main_function_resultt get_main_symbol( symbol_tablet &symbol_table, const irep_idt &main_class, message_handlert &message_handler, bool allow_no_body) { symbolt symbol; main_function_resultt res; messaget message(message_handler); // find main symbol if(config.main!="") { // Add java:: prefix std::string main_identifier="java::"+config.main; symbol_tablet::symbolst::const_iterator s_it; // Does it have a type signature? (':' suffix) if(config.main.rfind(':')==std::string::npos) { std::string prefix=main_identifier+':'; std::set<irep_idt> matches; for(const auto &s : symbol_table.symbols) if(has_prefix(id2string(s.first), prefix) && s.second.type.id()==ID_code) matches.insert(s.first); if(matches.empty()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; } else if(matches.size()==1) { s_it=symbol_table.symbols.find(*matches.begin()); assert(s_it!=symbol_table.symbols.end()); } else { message.error() << "main symbol `" << config.main << "' is ambiguous:\n"; for(const auto &s : matches) message.error() << " " << s << '\n'; message.error() << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; } } else { // just look it up s_it=symbol_table.symbols.find(main_identifier); if(s_it==symbol_table.symbols.end()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; } } // function symbol symbol=s_it->second; if(symbol.type.id()!=ID_code) { message.error() << "main symbol `" << config.main << "' not a function" << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; } // check if it has a body if(symbol.value.is_nil() && !allow_no_body) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; } } else { // no function given, we look for the main class assert(config.main==""); // are we given a main class? if(main_class.empty()) { res.main_function=symbol; res.error_found=false; res.stop_convert=true; return res; // silently ignore } std::string entry_method= id2string(main_class)+".main"; std::string prefix="java::"+entry_method+":"; // look it up std::set<irep_idt> matches; for(symbol_tablet::symbolst::const_iterator s_it=symbol_table.symbols.begin(); s_it!=symbol_table.symbols.end(); s_it++) { if(s_it->second.type.id()==ID_code && has_prefix(id2string(s_it->first), prefix)) matches.insert(s_it->first); } if(matches.empty()) { // Not found, silently ignore res.main_function=symbol; res.error_found=false; res.stop_convert=true; return res; } if(matches.size()>=2) { message.error() << "main method in `" << main_class << "' is ambiguous" << messaget::eom; res.main_function=symbolt(); res.error_found=true; res.stop_convert=true; return res; // give up with error, no main } // function symbol symbol=symbol_table.symbols.find(*matches.begin())->second; // check if it has a body if(symbol.value.is_nil() && !allow_no_body) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; res.main_function=symbol; res.error_found=true; res.stop_convert=true; return res; // give up with error } } res.main_function=symbol; res.error_found=false; res.stop_convert=false; return res; // give up with error }
void c_typecheck_baset::apply_asm_label( const irep_idt &asm_label, symbolt &symbol) { const irep_idt orig_name=symbol.name; // restrict renaming to functions and global variables; // procedure-local ones would require fixing the scope, as we // do for parameters below if(!asm_label.empty() && !symbol.is_type && (symbol.type.id()==ID_code || symbol.is_static_lifetime)) { symbol.name=asm_label; symbol.base_name=asm_label; } if(symbol.name!=orig_name) { if(!asm_label_map.insert( std::make_pair(orig_name, asm_label)).second) { if(asm_label_map[orig_name]!=asm_label) { error().source_location=symbol.location; error() << "error: replacing asm renaming " << asm_label_map[orig_name] << " by " << asm_label << eom; throw 0; } } } else if(asm_label.empty()) { asm_label_mapt::const_iterator entry= asm_label_map.find(symbol.name); if(entry!=asm_label_map.end()) { symbol.name=entry->second; symbol.base_name=entry->second; } } if(symbol.name!=orig_name && symbol.type.id()==ID_code && symbol.value.is_not_nil() && !symbol.is_macro) { const code_typet &code_type=to_code_type(symbol.type); for(code_typet::parameterst::const_iterator p_it=code_type.parameters().begin(); p_it!=code_type.parameters().end(); ++p_it) { const irep_idt &p_bn=p_it->get_base_name(); if(p_bn.empty()) continue; irep_idt p_id=id2string(orig_name)+"::"+id2string(p_bn); irep_idt p_new_id=id2string(symbol.name)+"::"+id2string(p_bn); if(!asm_label_map.insert( std::make_pair(p_id, p_new_id)).second) assert(asm_label_map[p_id]==p_new_id); } } }