Skip to content

Commit 74584f8

Browse files
committed
Export additional interface for remove-function-pointers
that takes the target map as argument. To avoid duplication we also refactor the existing functions a bit.
1 parent f16af50 commit 74584f8

File tree

2 files changed

+98
-32
lines changed

2 files changed

+98
-32
lines changed

src/goto-programs/remove_function_pointers.cpp

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,33 @@ class remove_function_pointerst
3838
bool only_resolve_const_fps,
3939
const goto_functionst &goto_functions);
4040

41-
void operator()(goto_functionst &goto_functions);
42-
41+
/// Call the function pointer removal via an operator
42+
/// \param goto_functions: functions to modify
43+
/// \param target_map: candidate functions
44+
void operator()(
45+
goto_functionst &goto_functions,
46+
const possible_fp_targets_mapt &target_map);
47+
48+
/// Call the function pointer removal within the \p goto_program
49+
/// \param goto_program: program to modify
50+
/// \param function_id: identifier of the function pointer to be removed
51+
/// \param target_map: candidate functions
4352
bool remove_function_pointers(
4453
goto_programt &goto_program,
45-
const irep_idt &function_id);
54+
const irep_idt &function_id,
55+
const possible_fp_targets_mapt &target_map);
4656

4757
// a set of function symbols
4858
using functionst = remove_const_function_pointerst::functionst;
4959

5060
/// Replace a call to a dynamic function at location
51-
/// target in the given goto-program by a case-split
61+
/// \p target in the given goto-program by a case-split
5262
/// over a given set of functions
5363
/// \param goto_program: The goto program that contains target
5464
/// \param function_id: Name of function containing the target
5565
/// \param target: location with function call with function pointer
5666
/// \param functions: The set of functions to consider
57-
void remove_function_pointer(
67+
void remove_function_pointer_non_const(
5868
goto_programt &goto_program,
5969
const irep_idt &function_id,
6070
goto_programt::targett target,
@@ -66,7 +76,7 @@ class remove_function_pointerst
6676
/// \param call_site: the call site of the function pointer under analysis
6777
/// \return the set of the potential functions
6878
functionst get_function_pointer_targets(
69-
const goto_modelt &goto_model,
79+
const goto_functionst &goto_functions,
7080
goto_programt::const_targett &call_site);
7181

7282
/// Go through a single function body and find all potential function the
@@ -78,6 +88,13 @@ class remove_function_pointerst
7888
const goto_programt &goto_program,
7989
goto_programt::const_targett &call_site);
8090

91+
/// Go through the whole model and find all potential function the pointer at
92+
/// all call sites
93+
/// \param goto_model: model to search for potential functions
94+
/// \return a map from ids to sets of function candidates
95+
possible_fp_targets_mapt
96+
get_function_pointer_targets(const goto_functionst &goto_functions);
97+
8198
protected:
8299
messaget log;
83100
const namespacet ns;
@@ -104,10 +121,12 @@ class remove_function_pointerst
104121
/// \param goto_program: The goto program that contains target
105122
/// \param function_id: Name of function containing the target
106123
/// \param target: location with function call with function pointer
107-
void remove_function_pointer(
124+
/// \param functions: potential candidate functions
125+
void remove_function_pointer_const(
108126
goto_programt &goto_program,
109127
const irep_idt &function_id,
110-
goto_programt::targett target);
128+
goto_programt::targett target,
129+
const functionst &functions);
111130

112131
std::unordered_set<irep_idt> address_taken;
113132

@@ -384,11 +403,11 @@ void remove_function_pointerst::try_remove_const_fp(
384403

385404
remove_function_pointerst::functionst
386405
remove_function_pointerst::get_function_pointer_targets(
387-
const goto_modelt &goto_model,
406+
const goto_functionst &goto_functions,
388407
goto_programt::const_targett &call_site)
389408
{
390409
functionst functions;
391-
for(const auto &function_pair : goto_model.goto_functions.function_map)
410+
for(const auto &function_pair : goto_functions.function_map)
392411
{
393412
const auto &function_body = function_pair.second.body;
394413
const auto &candidates =
@@ -445,15 +464,12 @@ remove_function_pointerst::get_function_pointer_targets(
445464
return functions;
446465
}
447466

448-
void remove_function_pointerst::remove_function_pointer(
467+
void remove_function_pointerst::remove_function_pointer_const(
449468
goto_programt &goto_program,
450469
const irep_idt &function_id,
451-
goto_programt::targett target)
470+
goto_programt::targett target,
471+
const functionst &functions)
452472
{
453-
goto_programt::const_targett const_target = target;
454-
const auto functions =
455-
get_function_pointer_targets(goto_program, const_target);
456-
457473
if(only_remove_const_function_pointers_called)
458474
{
459475
auto call = target->get_function_call();
@@ -468,11 +484,12 @@ void remove_function_pointerst::remove_function_pointer(
468484
// Since we haven't found functions, we would now resort to
469485
// replacing the function pointer with any function with a valid signature
470486
// Since we don't want to do that, we abort.
471-
remove_function_pointer(goto_program, function_id, target, functions);
487+
remove_function_pointer_non_const(
488+
goto_program, function_id, target, functions);
472489
}
473490
}
474491

475-
void remove_function_pointerst::remove_function_pointer(
492+
void remove_function_pointerst::remove_function_pointer_non_const(
476493
goto_programt &goto_program,
477494
const irep_idt &function_id,
478495
goto_programt::targett target,
@@ -501,7 +518,8 @@ void remove_function_pointerst::remove_function_pointer(
501518

502519
bool remove_function_pointerst::remove_function_pointers(
503520
goto_programt &goto_program,
504-
const irep_idt &function_id)
521+
const irep_idt &function_id,
522+
const possible_fp_targets_mapt &target_map)
505523
{
506524
bool did_something=false;
507525

@@ -512,7 +530,8 @@ bool remove_function_pointerst::remove_function_pointers(
512530

513531
if(code.function().id()==ID_dereference)
514532
{
515-
remove_function_pointer(goto_program, function_id, target);
533+
remove_function_pointer_const(
534+
goto_program, function_id, target, target_map.at(function_id));
516535
did_something=true;
517536
}
518537
}
@@ -523,7 +542,9 @@ bool remove_function_pointerst::remove_function_pointers(
523542
return did_something;
524543
}
525544

526-
void remove_function_pointerst::operator()(goto_functionst &functions)
545+
void remove_function_pointerst::operator()(
546+
goto_functionst &functions,
547+
const possible_fp_targets_mapt &target_map)
527548
{
528549
bool did_something=false;
529550

@@ -534,7 +555,7 @@ void remove_function_pointerst::operator()(goto_functionst &functions)
534555
{
535556
goto_programt &goto_program=f_it->second.body;
536557

537-
if(remove_function_pointers(goto_program, f_it->first))
558+
if(remove_function_pointers(goto_program, f_it->first, target_map))
538559
did_something=true;
539560
}
540561

@@ -559,7 +580,10 @@ bool remove_function_pointers(
559580
only_remove_const_fps,
560581
goto_functions);
561582

562-
return rfp.remove_function_pointers(goto_program, function_id);
583+
return rfp.remove_function_pointers(
584+
goto_program,
585+
function_id,
586+
rfp.get_function_pointer_targets(goto_functions));
563587
}
564588

565589
void remove_function_pointers(
@@ -577,7 +601,7 @@ void remove_function_pointers(
577601
only_remove_const_fps,
578602
goto_functions);
579603

580-
rfp(goto_functions);
604+
rfp(goto_functions, rfp.get_function_pointer_targets(goto_functions));
581605
}
582606

583607
void remove_function_pointers(message_handlert &_message_handler,
@@ -593,19 +617,28 @@ void remove_function_pointers(message_handlert &_message_handler,
593617
only_remove_const_fps);
594618
}
595619

596-
possible_fp_targets_mapt get_function_pointer_targets(
597-
message_handlert &message_handler,
598-
goto_modelt &goto_model)
620+
void remove_function_pointers(
621+
message_handlert &_message_handler,
622+
goto_modelt &goto_model,
623+
const possible_fp_targets_mapt &target_map,
624+
bool add_safety_assertion,
625+
bool only_remove_const_fps)
599626
{
600627
remove_function_pointerst rfp(
601-
message_handler,
628+
_message_handler,
602629
goto_model.symbol_table,
603-
false,
604-
false,
630+
add_safety_assertion,
631+
only_remove_const_fps,
605632
goto_model.goto_functions);
606633

634+
rfp(goto_model.goto_functions, target_map);
635+
}
636+
637+
possible_fp_targets_mapt
638+
remove_function_pointerst::get_function_pointer_targets(
639+
const goto_functionst &goto_functions)
640+
{
607641
possible_fp_targets_mapt target_map;
608-
const auto &goto_functions = goto_model.goto_functions;
609642
for(const auto &function_pair : goto_functions.function_map)
610643
{
611644
const auto &instructions = function_pair.second.body.instructions;
@@ -622,13 +655,27 @@ possible_fp_targets_mapt get_function_pointer_targets(
622655
.pointer())
623656
.get_identifier();
624657
target_map.emplace(
625-
function_id, rfp.get_function_pointer_targets(goto_model, target));
658+
function_id, get_function_pointer_targets(goto_functions, target));
626659
}
627660
}
628661
}
629662
return target_map;
630663
}
631664

665+
possible_fp_targets_mapt get_function_pointer_targets(
666+
message_handlert &message_handler,
667+
goto_modelt &goto_model)
668+
{
669+
remove_function_pointerst rfp(
670+
message_handler,
671+
goto_model.symbol_table,
672+
false,
673+
false,
674+
goto_model.goto_functions);
675+
676+
return rfp.get_function_pointer_targets(goto_model.goto_functions);
677+
}
678+
632679
goto_programt remove_function_pointerst::build_new_code(
633680
const functionst &functions,
634681
const code_function_callt &code,

src/goto-programs/remove_function_pointers.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class symbol_tablet;
2929
using possible_fp_targetst = remove_const_function_pointerst::functionst;
3030
using possible_fp_targets_mapt = std::map<irep_idt, possible_fp_targetst>;
3131

32+
/// Go through the whole model and find all potential function the pointer at
33+
/// all call sites
34+
/// \param message_handler: a message handler for reporting
35+
/// \param goto_model: model to search for potential functions
36+
/// \return a map from ids to sets of function candidates
3237
possible_fp_targets_mapt get_function_pointer_targets(
3338
message_handlert &message_handler,
3439
goto_modelt &goto_model);
@@ -41,6 +46,20 @@ void remove_function_pointers(
4146
bool add_safety_assertion,
4247
bool only_remove_const_fps=false);
4348

49+
/// Replace all calls to a dynamic function by a case-split over a given set of
50+
/// candidate functions
51+
/// \param message_handler: a message handler for reporting
52+
/// \param goto_model: model to search for potential functions
53+
/// \param target_map: candidate functions
54+
/// \param add_safety_assertion: check that at least one function matches
55+
/// \param only_remove_const_fps: restrict the pointer remove to const
56+
void remove_function_pointers(
57+
message_handlert &_message_handler,
58+
goto_modelt &goto_model,
59+
const possible_fp_targets_mapt &target_map,
60+
bool add_safety_assertion,
61+
bool only_remove_const_fps = false);
62+
4463
void remove_function_pointers(
4564
message_handlert &_message_handler,
4665
symbol_tablet &symbol_table,

0 commit comments

Comments
 (0)