bool remove_virtual_functionst::remove_virtual_functions( goto_programt &goto_program) { bool did_something=false; Forall_goto_program_instructions(target, goto_program) if(target->is_function_call()) { const code_function_callt &code= to_code_function_call(target->code); if(code.function().id()==ID_virtual_function) { remove_virtual_function(goto_program, target); did_something=true; } } if(did_something) { goto_program.update(); } return did_something; }
void string_instrumentationt::do_function_call( goto_programt &dest, goto_programt::targett target) { code_function_callt &call= to_code_function_call(target->code); exprt &function=call.function(); //const exprt &lhs=call.lhs(); if(function.id()=="symbol") { const irep_idt &identifier= to_symbol_expr(function).get_identifier(); if(identifier=="c::strcoll") { } else if(identifier=="c::strncmp") do_strncmp(dest, target, call); else if(identifier=="c::strxfrm") { } else if(identifier=="c::strchr") do_strchr(dest, target, call); else if(identifier=="c::strcspn") { } else if(identifier=="c::strpbrk") { } else if(identifier=="c::strrchr") do_strrchr(dest, target, call); else if(identifier=="c::strspn") { } else if(identifier=="c::strerror") do_strerror(dest, target, call); else if(identifier=="c::strstr") do_strstr(dest, target, call); else if(identifier=="c::strtok") do_strtok(dest, target, call); else if(identifier=="c::sprintf") do_sprintf(dest, target, call); else if(identifier=="c::snprintf") do_snprintf(dest, target, call); else if(identifier=="c::fscanf") do_fscanf(dest, target, call); dest.update(); } }
void loop_transformt::transform(goto_programt &goto_program) { goto_program.compute_incoming_edges(); // pass 1: simple stuff Forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { assert(it->targets.size()==1); goto_programt::targett begin = it->targets.front(); goto_programt::targett end = it; split_multi_head(goto_program, begin, end); transform_do_while(goto_program, begin, end); move_returns(goto_program, begin, end); } // pass 2: loop simulation Forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { goto_programt::targett begin = it->targets.front(); goto_programt::targett end = it; std::set<goto_programt::targett> entries; std::set<goto_programt::targett> exits; analyze(goto_program, begin, end, entries, exits); transform(goto_program, begin, end, entries, exits); it=end; } goto_program.update(); #if 1 // Another run for debugging forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { goto_programt::const_targett begin = it->targets.front(); goto_programt::const_targett end = it; run_checks(goto_program, begin, end); } #endif }
void loop_transformt::move_returns( goto_programt &program, goto_programt::targett begin, goto_programt::targett end) { goto_programt::targett postend = end; postend++; std::list<goto_programt::targett> returns; for(goto_programt::targett it = begin; it!=end; it++) { if(it->is_return()) returns.push_back(it); } if(returns.size()>0) { for(std::list<goto_programt::targett>::const_iterator it = returns.begin(); it!=returns.end(); it++) { goto_programt::targett newret = program.insert_before(postend); newret->swap(**it); newret->location_number = postend->location_number; (*it)->make_goto(newret); // this creates far exits, // which will be fixed lateron } // fix the loop exit goto_programt::targett firstafter = end; firstafter++; goto_programt::targett loopexit = program.insert_before(firstafter); loopexit->make_goto(postend); program.update(); } }
void loop_transformt::transform_do_while( goto_programt &program, goto_programt::targett &begin, goto_programt::targett &end) const { if(!end->guard.is_true()) { #if 0 std::cout << "TRANSFORM DO-WHILE" << std::endl; #endif goto_programt::targett next = end; next++; assert(next!=program.instructions.end()); goto_programt::instructiont newguard; newguard.make_goto(next); newguard.guard = end->guard; newguard.guard.make_not(); newguard.location = end->location; end->guard.make_true(); unsigned ln = end->location_number; // doesn't get swapped program.insert_before_swap(end, newguard); // end now points to the new guard goto_programt::targett old_guard = end; old_guard++; end->location_number=ln; old_guard->location_number=ln; program.update(); #if 0 std::cout << "Transformed: " << std::endl; goto_programt::const_targett it = begin; for (; it!=end; it++) program.output_instruction(ns, "", std::cout, it); program.output_instruction(ns, "", std::cout, it); #endif } }
void convert( const irept &irep, goto_programt &program ) { assert(irep.id()=="goto-program"); program.instructions.clear(); std::list< std::list<unsigned> > number_targets_list; // convert instructions back const irept::subt &subs = irep.get_sub(); for (irept::subt::const_iterator it=subs.begin(); it!=subs.end(); it++) { program.instructions.push_back(goto_programt::instructiont()); convert(*it, program.instructions.back()); number_targets_list.push_back(std::list<unsigned>()); const irept &targets=it->find(ID_targets); const irept::subt &tsubs=targets.get_sub(); for (irept::subt::const_iterator tit=tsubs.begin(); tit!=tsubs.end(); tit++) { number_targets_list.back().push_back( unsafe_string2unsigned(tit->id_string())); } } program.compute_location_numbers(); // resolve targets std::list< std::list<unsigned> >::iterator nit= number_targets_list.begin(); for(goto_programt::instructionst::iterator lit= program.instructions.begin(); lit!=program.instructions.end() && nit!=number_targets_list.end(); lit++, nit++) { for (std::list<unsigned>::iterator tit=nit->begin(); tit!=nit->end(); tit++) { goto_programt::targett fit=program.instructions.begin(); for(;fit!=program.instructions.end();fit++) { if (fit->location_number==*tit) { lit->targets.push_back(fit); break; } } if (fit==program.instructions.end()) { std::cout << "Warning: could not resolve target link " << "during irep->goto_program translation." << std::endl; throw 0; } } } program.update(); }
void loop_transformt::split_multi_head( goto_programt &program, goto_programt::targett begin, goto_programt::targett end) { #if 0 std::cout << "SPLIT MULTI-HEAD (" << begin->incoming_edges.size() << ")" << std::endl; #endif unsigned dontmatter = 0; goto_programt::targett prev = begin; prev--; forall_incoming_edges(it, begin) { if((*it)==prev) dontmatter++; else if((*it)==end) dontmatter++; } if(begin->incoming_edges.size() > dontmatter) { #if 0 std::cout << "Splitting " << begin->incoming_edges.size() << "-head" << std::endl; #endif goto_programt::targett newskip = program.insert_before(begin); newskip->make_skip(); newskip->location_number = begin->location_number; newskip->function = begin->function; newskip->location = begin->location; // redirect gotos forall_incoming_edges(it, begin) { const goto_programt::targett &from = *it; if(from!=prev && from!=end && from->is_goto() && from->targets.front()==begin) // gotos right before the loop // aren't necessarily jumping to begin { assert(from->targets.size()==1); from->targets.clear(); from->targets.push_back(newskip); } } program.update(); #if 0 namespacet ns(context); std::cout << "Split loop: " << std::endl; goto_programt::const_targett it = newskip; for (; it!=end; it++) program.output_instruction(ns, "", std::cout, it); program.output_instruction(ns, "", std::cout, it); #endif assert(begin->incoming_edges.size()<=2); }
void convert(const xmlt &xml, goto_programt &goto_program) { goto_program.clear(); goto_programt::instructionst &instructions = goto_program.instructions; xmlt::elementst::const_iterator it = xml.elements.begin(); for(; it != xml.elements.end(); it++) { goto_programt::targett inst = goto_program.add_instruction(); inst->targets.clear(); if(it->name=="goto") { inst->type = GOTO; } else if(it->name=="assume") { inst->type = ASSUME; } else if(it->name=="assert") { inst->type = ASSERT; } else if(it->name=="skip") { inst->type = SKIP; } else if(it->name=="end_function") { inst->type = END_FUNCTION; } else if(it->name=="location") { inst->type = LOCATION; } else if(it->name=="dead") { inst->type = DEAD; } else if(it->name=="atomic_begin") { inst->type = ATOMIC_BEGIN; } else if(it->name=="atomic_end") { inst->type = ATOMIC_END; } else if(it->name=="return") { inst->make_return(); } else if(it->name=="instruction") // OTHER { inst->make_other(); } else if(it->name=="assign") { inst->make_other(); inst->type=ASSIGN; } else if(it->name=="functioncall") { inst->make_other(); inst->type=FUNCTION_CALL; } else if(it->name=="thread_start") { inst->type = START_THREAD; } else if(it->name=="thread_end") { inst->type = END_THREAD; } else { std::cout << "Unknown instruction type encountered (" << it->name << ")"; std::cout << std::endl; return; } xmlt::elementst::const_iterator eit = it->elements.begin(); for(; eit != it->elements.end(); eit++) { if(eit->name=="location") { convert(*eit, inst->location); } else if(eit->name=="variables") { } else if(eit->name=="labels") { xmlt::elementst::const_iterator lit = eit->elements.begin(); for(; lit != eit->elements.end(); lit++) { if(lit->name=="label") { std::string ls = lit->get_attribute("name"); inst->labels.push_back(ls); } else { std::cout << "Unknown node in labels section." << std::endl; return; } } } else if(eit->name=="guard") { inst->guard.remove("value"); convert(*eit, inst->guard); } else if(eit->name=="code") { convert(*eit, inst->code); } else if(eit->name=="targets") { // Don't do anything here, we'll need a second run for that } else if(eit->name=="comment") { inst->location.set("comment", eit->data); } else if(eit->name=="function") { inst->function = eit->data; } } } // assign line numbers goto_program.compute_location_numbers(); // second run, for targets goto_programt::targett ins_it = instructions.begin(); it = xml.elements.begin(); for(; it != xml.elements.end() && ins_it!=instructions.end(); it++) { xmlt::elementst::const_iterator eit = it->elements.begin(); for(; eit != it->elements.end(); eit++) { if(eit->name=="targets") { xmlt::elementst::const_iterator tit = eit->elements.begin(); for(; tit != eit->elements.end(); tit++) { if(tit->name=="target") { goto_programt::targett tins = find_instruction(xml, instructions, tit->data); if(tins != instructions.end()) { // Here we insert the iterators that somehow seem // to be strange afterwards (see line 87) ins_it->targets.push_back(tins); } else { std::cout << "Warning: instruction not found when " "resolving target links." << std::endl; } } else { std::cout << "Unknown node in targets section." << std::endl; return; } } } } ins_it++; } // resolve links goto_program.update(); // std::cout << "TNI: " << goto_program.target_numbers.size() << std::endl; }