Introduction
The c++ (cpp) type_mapt example is extracted from the most popular open source projects, you can refer to the following example for usage.
Programming language: C++ (Cpp)
Class/type: type_mapt
Example#1
void remove_function_pointerst::remove_function_pointer(
goto_programt &goto_program,
goto_programt::targett target)
{
const code_function_callt &code=
to_code_function_call(target->code);
const exprt &function=code.function();
// this better have the right type
const code_typet &call_type=to_code_type(function.type());
assert(function.id()==ID_dereference);
assert(function.operands().size()==1);
const exprt &pointer=function.op0();
typedef std::list<exprt> functionst;
functionst functions;
// get all type-compatible functions
// whose address is ever taken
for(type_mapt::const_iterator f_it=
type_map.begin();
f_it!=type_map.end();
f_it++)
{
// address taken?
if(address_taken.find(f_it->first)==address_taken.end())
continue;
// type-compatible?
if(!is_type_compatible(call_type, f_it->second))
continue;
symbol_exprt expr;
expr.type()=f_it->second;
expr.set_identifier(f_it->first);
functions.push_back(expr);
}
// the final target is a skip
goto_programt final_skip;
goto_programt::targett t_final=final_skip.add_instruction();
t_final->make_skip();
// build the calls and gotos
goto_programt new_code_calls;
goto_programt new_code_gotos;
for(functionst::const_iterator
it=functions.begin();
it!=functions.end();
it++)
{
// call function
goto_programt::targett t1=new_code_calls.add_instruction();
t1->make_function_call(code);
to_code_function_call(t1->code).function()=*it;
// the signature of the function might not match precisely
fix_argument_types(to_code_function_call(t1->code));
fix_return_type(to_code_function_call(t1->code), new_code_calls);
// goto final
goto_programt::targett t3=new_code_calls.add_instruction();
t3->make_goto(t_final, true_exprt());
// goto to call
address_of_exprt address_of;
address_of.object()=*it;
address_of.type()=pointer_typet();
address_of.type().subtype()=it->type();
if(address_of.type()!=pointer.type())
address_of.make_typecast(pointer.type());
goto_programt::targett t4=new_code_gotos.add_instruction();
t4->make_goto(t1, equal_exprt(pointer, address_of));
}
// fall-through
if(add_safety_assertion)
{
goto_programt::targett t=new_code_gotos.add_instruction();
t->make_assertion(false_exprt());
t->location.set(ID_property, "pointer dereference");
t->location.set(ID_comment, "invalid function pointer");
}
goto_programt new_code;
// patch them all together
new_code.destructive_append(new_code_gotos);
new_code.destructive_append(new_code_calls);
new_code.destructive_append(final_skip);
// set locations
Forall_goto_program_instructions(it, new_code)
{
irep_idt property=it->location.get_property();
irep_idt comment=it->location.get_comment();
it->location=target->location;
it->function=target->function;
if(!property.empty()) it->location.set_property(property);
if(!comment.empty()) it->location.set_comment(comment);
}
Example#2File:
remove_function_pointers.cppProject:
diffblue/cbmc
void remove_function_pointerst::remove_function_pointer(
goto_programt &goto_program,
goto_programt::targett target)
{
const code_function_callt &code=
to_code_function_call(target->code);
const exprt &function=code.function();
// this better have the right type
code_typet call_type=to_code_type(function.type());
// refine the type in case the forward declaration was incomplete
if(call_type.has_ellipsis() &&
call_type.parameters().empty())
{
call_type.remove_ellipsis();
forall_expr(it, code.arguments())
call_type.parameters().push_back(
code_typet::parametert(it->type()));
}
assert(function.id()==ID_dereference);
assert(function.operands().size()==1);
const exprt &pointer=function.op0();
// Is this simple?
if(pointer.id()==ID_address_of &&
to_address_of_expr(pointer).object().id()==ID_symbol)
{
to_code_function_call(target->code).function()=
to_address_of_expr(pointer).object();
return;
}
typedef std::list<exprt> functionst;
functionst functions;
bool return_value_used=code.lhs().is_not_nil();
// get all type-compatible functions
// whose address is ever taken
for(type_mapt::const_iterator f_it=
type_map.begin();
f_it!=type_map.end();
f_it++)
{
// address taken?
if(address_taken.find(f_it->first)==address_taken.end())
continue;
// type-compatible?
if(!is_type_compatible(return_value_used, call_type, f_it->second))
continue;
if(f_it->first=="pthread_mutex_cleanup")
continue;
symbol_exprt expr;
expr.type()=f_it->second;
expr.set_identifier(f_it->first);
functions.push_back(expr);
}
// the final target is a skip
goto_programt final_skip;
goto_programt::targett t_final=final_skip.add_instruction();
t_final->make_skip();
// build the calls and gotos
goto_programt new_code_calls;
goto_programt new_code_gotos;
for(functionst::const_iterator
it=functions.begin();
it!=functions.end();
it++)
{
// call function
goto_programt::targett t1=new_code_calls.add_instruction();
t1->make_function_call(code);
to_code_function_call(t1->code).function()=*it;
// the signature of the function might not match precisely
fix_argument_types(to_code_function_call(t1->code));
fix_return_type(to_code_function_call(t1->code), new_code_calls);
// goto final
goto_programt::targett t3=new_code_calls.add_instruction();
t3->make_goto(t_final, true_exprt());
// goto to call
address_of_exprt address_of;
address_of.object()=*it;
address_of.type()=pointer_typet();
address_of.type().subtype()=it->type();
if(address_of.type()!=pointer.type())
address_of.make_typecast(pointer.type());
goto_programt::targett t4=new_code_gotos.add_instruction();
t4->make_goto(t1, equal_exprt(pointer, address_of));
}
// fall-through
if(add_safety_assertion)
{
goto_programt::targett t=new_code_gotos.add_instruction();
t->make_assertion(false_exprt());
t->source_location.set_property_class("pointer dereference");
t->source_location.set_comment("invalid function pointer");
}
goto_programt new_code;
// patch them all together
new_code.destructive_append(new_code_gotos);
new_code.destructive_append(new_code_calls);
new_code.destructive_append(final_skip);
// set locations
Forall_goto_program_instructions(it, new_code)
{
irep_idt property_class=it->source_location.get_property_class();
irep_idt comment=it->source_location.get_comment();
it->source_location=target->source_location;
it->function=target->function;
if(!property_class.empty()) it->source_location.set_property_class(property_class);
if(!comment.empty()) it->source_location.set_comment(comment);
}