@@ -38,35 +38,45 @@ class remove_function_pointerst
38
38
bool only_resolve_const_fps,
39
39
const goto_functionst &goto_functions);
40
40
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
43
52
bool remove_function_pointers (
44
53
goto_programt &goto_program,
45
- const irep_idt &function_id);
54
+ const irep_idt &function_id,
55
+ const possible_fp_targets_mapt &target_map);
46
56
47
57
// a set of function symbols
48
58
using functionst = remove_const_function_pointerst::functionst;
49
59
50
60
// / 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
52
62
// / over a given set of functions
53
63
// / \param goto_program: The goto program that contains target
54
64
// / \param function_id: Name of function containing the target
55
65
// / \param target: location with function call with function pointer
56
- // / \param functions: The set of functions to consider
57
- void remove_function_pointer (
66
+ // / \param functions: the set of functions to consider
67
+ void remove_function_pointer_non_const (
58
68
goto_programt &goto_program,
59
69
const irep_idt &function_id,
60
70
goto_programt::targett target,
61
71
const functionst &functions);
62
72
63
73
// / Go through the whole model and find all potential function the pointer at
64
74
// / \p call site may point to
65
- // / \param goto_model: model to search for potential functions
75
+ // / \param goto_functions: goto functions to search for potential candidates
66
76
// / \param call_site: the call site of the function pointer under analysis
67
77
// / \return the set of the potential functions
68
78
functionst get_function_pointer_targets (
69
- const goto_modelt &goto_model ,
79
+ const goto_functionst &goto_functions ,
70
80
goto_programt::const_targett &call_site);
71
81
72
82
// / Go through a single function body and find all potential function the
@@ -78,6 +88,13 @@ class remove_function_pointerst
78
88
const goto_programt &goto_program,
79
89
goto_programt::const_targett &call_site);
80
90
91
+ // / Go through the whole model and find all potential function the pointer at
92
+ // / all call sites
93
+ // / \param goto_functions: goto functions to search for potential candidates
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
+
81
98
protected:
82
99
messaget log;
83
100
const namespacet ns;
@@ -137,10 +154,12 @@ class remove_function_pointerst
137
154
// / \param goto_program: The goto program that contains target
138
155
// / \param function_id: Name of function containing the target
139
156
// / \param target: location with function call with function pointer
140
- void remove_function_pointer (
157
+ // / \param functions: the set of functions to consider
158
+ void remove_function_pointer_const (
141
159
goto_programt &goto_program,
142
160
const irep_idt &function_id,
143
- goto_programt::targett target);
161
+ goto_programt::targett target,
162
+ const functionst &functions);
144
163
145
164
std::unordered_set<irep_idt> address_taken;
146
165
@@ -173,10 +192,12 @@ class remove_function_pointerst
173
192
// / \param goto_program: the function body to run the const_removal_check on
174
193
// / \param functions: the list of functions the const removal found
175
194
// / \param pointer: the pointer to be resolved
195
+ // / \param callee_id: function id
176
196
void try_remove_const_fp (
177
197
const goto_programt &goto_program,
178
198
functionst &functions,
179
- const exprt &pointer);
199
+ const exprt &pointer,
200
+ const irep_idt &callee_id);
180
201
181
202
// / From *fp() build the following sequence of instructions:
182
203
// /
@@ -424,11 +445,11 @@ void remove_function_pointerst::try_remove_const_fp(
424
445
425
446
remove_function_pointerst::functionst
426
447
remove_function_pointerst::get_function_pointer_targets (
427
- const goto_modelt &goto_model ,
448
+ const goto_functionst &goto_functions ,
428
449
goto_programt::const_targett &call_site)
429
450
{
430
451
functionst functions;
431
- for (const auto &function_pair : goto_model. goto_functions .function_map )
452
+ for (const auto &function_pair : goto_functions.function_map )
432
453
{
433
454
const auto &function_body = function_pair.second .body ;
434
455
const auto &candidates =
@@ -486,15 +507,12 @@ remove_function_pointerst::get_function_pointer_targets(
486
507
return functions;
487
508
}
488
509
489
- void remove_function_pointerst::remove_function_pointer (
510
+ void remove_function_pointerst::remove_function_pointer_const (
490
511
goto_programt &goto_program,
491
512
const irep_idt &function_id,
492
- goto_programt::targett target)
513
+ goto_programt::targett target,
514
+ const functionst &functions)
493
515
{
494
- goto_programt::const_targett const_target = target;
495
- const auto functions =
496
- get_function_pointer_targets (goto_program, const_target);
497
-
498
516
auto callee_id = get_callee_id (target->get_function_call ().function ());
499
517
if (was_only_remove_const_function_pointers_called (callee_id))
500
518
{
@@ -511,11 +529,12 @@ void remove_function_pointerst::remove_function_pointer(
511
529
// Since we haven't found functions, we would now resort to
512
530
// replacing the function pointer with any function with a valid signature
513
531
// Since we don't want to do that, we abort.
514
- remove_function_pointer (goto_program, function_id, target, functions);
532
+ remove_function_pointer_non_const (
533
+ goto_program, function_id, target, functions);
515
534
}
516
535
}
517
536
518
- void remove_function_pointerst::remove_function_pointer (
537
+ void remove_function_pointerst::remove_function_pointer_non_const (
519
538
goto_programt &goto_program,
520
539
const irep_idt &function_id,
521
540
goto_programt::targett target,
@@ -544,18 +563,23 @@ void remove_function_pointerst::remove_function_pointer(
544
563
545
564
bool remove_function_pointerst::remove_function_pointers (
546
565
goto_programt &goto_program,
547
- const irep_idt &function_id)
566
+ const irep_idt &function_id,
567
+ const possible_fp_targets_mapt &target_map)
548
568
{
549
569
bool did_something=false ;
550
570
551
571
Forall_goto_program_instructions (target, goto_program)
552
572
if (target->is_function_call ())
553
573
{
554
574
const code_function_callt &code = target->get_function_call ();
575
+ const auto &callee = code.function ();
555
576
556
577
if (code.function ().id ()==ID_dereference)
557
578
{
558
- remove_function_pointer (goto_program, function_id, target);
579
+ auto callee_id = get_callee_id (callee);
580
+ CHECK_RETURN (target_map.count (callee_id) > 0 );
581
+ remove_function_pointer_const (
582
+ goto_program, function_id, target, target_map.at (callee_id));
559
583
did_something=true ;
560
584
}
561
585
}
@@ -566,18 +590,20 @@ bool remove_function_pointerst::remove_function_pointers(
566
590
return did_something;
567
591
}
568
592
569
- void remove_function_pointerst::operator ()(goto_functionst &functions)
593
+ void remove_function_pointerst::operator ()(
594
+ goto_functionst &functions,
595
+ const possible_fp_targets_mapt &target_map)
570
596
{
571
597
bool did_something=false ;
572
598
573
- for (goto_functionst::function_mapt::iterator f_it=
574
- functions.function_map .begin ();
575
- f_it!= functions.function_map .end ();
599
+ for (goto_functionst::function_mapt::iterator f_it =
600
+ functions.function_map .begin ();
601
+ f_it != functions.function_map .end ();
576
602
f_it++)
577
603
{
578
604
goto_programt &goto_program=f_it->second .body ;
579
605
580
- if (remove_function_pointers (goto_program, f_it->first ))
606
+ if (remove_function_pointers (goto_program, f_it->first , target_map ))
581
607
did_something=true ;
582
608
}
583
609
@@ -602,7 +628,10 @@ bool remove_function_pointers(
602
628
only_remove_const_fps,
603
629
goto_functions);
604
630
605
- return rfp.remove_function_pointers (goto_program, function_id);
631
+ return rfp.remove_function_pointers (
632
+ goto_program,
633
+ function_id,
634
+ rfp.get_function_pointer_targets (goto_functions));
606
635
}
607
636
608
637
void remove_function_pointers (
@@ -620,7 +649,7 @@ void remove_function_pointers(
620
649
only_remove_const_fps,
621
650
goto_functions);
622
651
623
- rfp (goto_functions);
652
+ rfp (goto_functions, rfp. get_function_pointer_targets (goto_functions) );
624
653
}
625
654
626
655
void remove_function_pointers (message_handlert &_message_handler,
@@ -636,19 +665,28 @@ void remove_function_pointers(message_handlert &_message_handler,
636
665
only_remove_const_fps);
637
666
}
638
667
639
- possible_fp_targets_mapt get_function_pointer_targets (
640
- message_handlert &message_handler,
641
- goto_modelt &goto_model)
668
+ void remove_function_pointers (
669
+ message_handlert &_message_handler,
670
+ goto_modelt &goto_model,
671
+ const possible_fp_targets_mapt &target_map,
672
+ bool add_safety_assertion,
673
+ bool only_remove_const_fps)
642
674
{
643
675
remove_function_pointerst rfp (
644
- message_handler ,
676
+ _message_handler ,
645
677
goto_model.symbol_table ,
646
- false ,
647
- false ,
678
+ add_safety_assertion ,
679
+ only_remove_const_fps ,
648
680
goto_model.goto_functions );
649
681
682
+ rfp (goto_model.goto_functions , target_map);
683
+ }
684
+
685
+ possible_fp_targets_mapt
686
+ remove_function_pointerst::get_function_pointer_targets (
687
+ const goto_functionst &goto_functions)
688
+ {
650
689
possible_fp_targets_mapt target_map;
651
- const auto &goto_functions = goto_model.goto_functions ;
652
690
for (const auto &function_pair : goto_functions.function_map )
653
691
{
654
692
const auto &instructions = function_pair.second .body .instructions ;
@@ -673,6 +711,20 @@ possible_fp_targets_mapt get_function_pointer_targets(
673
711
return target_map;
674
712
}
675
713
714
+ possible_fp_targets_mapt get_function_pointer_targets (
715
+ message_handlert &message_handler,
716
+ goto_modelt &goto_model)
717
+ {
718
+ remove_function_pointerst rfp (
719
+ message_handler,
720
+ goto_model.symbol_table ,
721
+ false ,
722
+ false ,
723
+ goto_model.goto_functions );
724
+
725
+ return rfp.get_function_pointer_targets (goto_model.goto_functions );
726
+ }
727
+
676
728
goto_programt remove_function_pointerst::build_new_code (
677
729
const functionst &functions,
678
730
const code_function_callt &code,
0 commit comments