Skip to content

Commit 03187b6

Browse files
committed
Track the state of function-pointer-removal
on a per-callee basis. To prevent the state for one callee to be used when removing pointers for another callee.
1 parent 1fa9a38 commit 03187b6

File tree

1 file changed

+62
-23
lines changed

1 file changed

+62
-23
lines changed

src/goto-programs/remove_function_pointers.cpp

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,42 @@ class remove_function_pointerst
9494

9595
// Internal variables for communication between function pointer collection
9696
// and the call modification.
97-
bool remove_const_found_functions;
98-
bool does_remove_const_success;
99-
bool only_remove_const_function_pointers_called;
97+
std::map<irep_idt, bool> remove_const_found_functions;
98+
std::map<irep_idt, bool> does_remove_const_success;
99+
std::map<irep_idt, bool> only_remove_const_function_pointers_called;
100+
101+
void set_remove_const_found_functions(const irep_idt &id, bool value)
102+
{
103+
if(remove_const_found_functions.count(id) == 0 || !value)
104+
remove_const_found_functions[id] = value;
105+
}
106+
void set_does_remove_const_success(const irep_idt &id, bool value)
107+
{
108+
if(does_remove_const_success.count(id) == 0 || value)
109+
does_remove_const_success[id] = value;
110+
}
111+
void
112+
set_only_remove_const_function_pointers_called(const irep_idt &id, bool value)
113+
{
114+
if(only_remove_const_function_pointers_called.count(id) == 0 || !value)
115+
only_remove_const_function_pointers_called[id] = value;
116+
}
117+
118+
bool did_remove_const_success(const irep_idt &id) const
119+
{
120+
CHECK_RETURN(does_remove_const_success.count(id) > 0);
121+
return does_remove_const_success.at(id);
122+
}
123+
bool was_only_remove_const_function_pointers_called(const irep_idt &id) const
124+
{
125+
CHECK_RETURN(only_remove_const_function_pointers_called.count(id) > 0);
126+
return only_remove_const_function_pointers_called.at(id);
127+
}
128+
bool did_remove_const_found_functions(const irep_idt &id) const
129+
{
130+
CHECK_RETURN(remove_const_found_functions.count(id) > 0);
131+
return remove_const_found_functions.at(id);
132+
}
100133

101134
/// Replace a call to a dynamic function at location
102135
/// target in the given goto-program by determining
@@ -357,21 +390,22 @@ code_typet remove_function_pointerst::refine_call_type(
357390
void remove_function_pointerst::try_remove_const_fp(
358391
const goto_programt &goto_program,
359392
functionst &functions,
360-
const exprt &pointer)
393+
const exprt &pointer,
394+
const irep_idt &callee_id)
361395
{
362396
PRECONDITION(functions.empty());
363397

364398
does_remove_constt const_removal_check(goto_program, ns);
365399
const auto does_remove_const = const_removal_check();
366-
does_remove_const_success = does_remove_const.first;
400+
set_does_remove_const_success(callee_id, does_remove_const.first);
367401

368-
if(does_remove_const_success)
402+
if(does_remove_const.first)
369403
{
370404
log.warning().source_location = does_remove_const.second;
371405
log.warning() << "cast from const to non-const pointer found, "
372406
<< "only worst case function pointer removal will be done."
373407
<< messaget::eom;
374-
remove_const_found_functions = false;
408+
set_remove_const_found_functions(callee_id, false);
375409
}
376410
else
377411
{
@@ -382,8 +416,9 @@ void remove_function_pointerst::try_remove_const_fp(
382416
// however, it is possible for found_functions to be true and functions
383417
// to be empty (this happens if the pointer can only resolve to the null
384418
// pointer)
385-
remove_const_found_functions = fpr(pointer, functions);
386-
CHECK_RETURN(remove_const_found_functions || functions.empty());
419+
bool temp = fpr(pointer, functions);
420+
set_remove_const_found_functions(callee_id, temp);
421+
CHECK_RETURN(temp || functions.empty());
387422
}
388423
}
389424

@@ -415,13 +450,14 @@ remove_function_pointerst::get_function_pointer_targets(
415450
const auto &refined_call_type = refine_call_type(function.type(), code);
416451

417452
functionst functions;
418-
try_remove_const_fp(goto_program, functions, function.pointer());
453+
auto callee_id = get_callee_id(function);
454+
try_remove_const_fp(goto_program, functions, function.pointer(), callee_id);
419455

420-
only_remove_const_function_pointers_called =
421-
!does_remove_const_success && functions.size() == 1;
456+
set_only_remove_const_function_pointers_called(
457+
callee_id, !did_remove_const_success(callee_id) && functions.size() == 1);
422458
if(
423-
!only_remove_const_function_pointers_called &&
424-
!remove_const_found_functions && !only_resolve_const_fps)
459+
!was_only_remove_const_function_pointers_called(callee_id) &&
460+
!did_remove_const_found_functions(callee_id) && !only_resolve_const_fps)
425461
{
426462
// get all type-compatible functions
427463
// whose address is ever taken
@@ -459,13 +495,15 @@ void remove_function_pointerst::remove_function_pointer(
459495
const auto functions =
460496
get_function_pointer_targets(goto_program, const_target);
461497

462-
if(only_remove_const_function_pointers_called)
498+
auto callee_id = get_callee_id(target->get_function_call().function());
499+
if(was_only_remove_const_function_pointers_called(callee_id))
463500
{
464501
auto call = target->get_function_call();
465502
call.function() = *functions.cbegin();
466503
target->set_function_call(call);
467504
}
468-
else if(remove_const_found_functions || !only_resolve_const_fps)
505+
else if(
506+
did_remove_const_found_functions(callee_id) || !only_resolve_const_fps)
469507
{
470508
// If this mode is enabled, we only remove function pointers
471509
// that we can resolve either to an exact function, or an exact subset
@@ -621,13 +659,14 @@ possible_fp_targets_mapt get_function_pointer_targets(
621659
target->is_function_call() &&
622660
target->get_function_call().function().id() == ID_dereference)
623661
{
624-
const auto &function_id =
625-
to_symbol_expr(
626-
to_dereference_expr(target->get_function_call().function())
627-
.pointer())
628-
.get_identifier();
629-
target_map.emplace(
630-
function_id, rfp.get_function_pointer_targets(goto_model, target));
662+
const auto &function = target->get_function_call().function();
663+
irep_idt callee_id = get_callee_id(function);
664+
CHECK_RETURN(!callee_id.empty());
665+
if(target_map.count(callee_id) == 0)
666+
{
667+
target_map.emplace(
668+
callee_id, get_function_pointer_targets(goto_functions, target));
669+
}
631670
}
632671
}
633672
}

0 commit comments

Comments
 (0)