@@ -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,
@@ -542,18 +561,23 @@ void remove_function_pointerst::remove_function_pointer(
542
561
543
562
bool remove_function_pointerst::remove_function_pointers (
544
563
goto_programt &goto_program,
545
- const irep_idt &function_id)
564
+ const irep_idt &function_id,
565
+ const possible_fp_targets_mapt &target_map)
546
566
{
547
567
bool did_something=false ;
548
568
549
569
Forall_goto_program_instructions (target, goto_program)
550
570
if (target->is_function_call ())
551
571
{
552
572
const code_function_callt &code = target->get_function_call ();
573
+ const auto &callee = code.function ();
553
574
554
575
if (code.function ().id ()==ID_dereference)
555
576
{
556
- remove_function_pointer (goto_program, function_id, target);
577
+ auto callee_id = get_callee_id (callee);
578
+ CHECK_RETURN (target_map.count (callee_id) > 0 );
579
+ remove_function_pointer_const (
580
+ goto_program, function_id, target, target_map.at (callee_id));
557
581
did_something=true ;
558
582
}
559
583
}
@@ -564,18 +588,20 @@ bool remove_function_pointerst::remove_function_pointers(
564
588
return did_something;
565
589
}
566
590
567
- void remove_function_pointerst::operator ()(goto_functionst &functions)
591
+ void remove_function_pointerst::operator ()(
592
+ goto_functionst &functions,
593
+ const possible_fp_targets_mapt &target_map)
568
594
{
569
595
bool did_something=false ;
570
596
571
- for (goto_functionst::function_mapt::iterator f_it=
572
- functions.function_map .begin ();
573
- f_it!= functions.function_map .end ();
597
+ for (goto_functionst::function_mapt::iterator f_it =
598
+ functions.function_map .begin ();
599
+ f_it != functions.function_map .end ();
574
600
f_it++)
575
601
{
576
602
goto_programt &goto_program=f_it->second .body ;
577
603
578
- if (remove_function_pointers (goto_program, f_it->first ))
604
+ if (remove_function_pointers (goto_program, f_it->first , target_map ))
579
605
did_something=true ;
580
606
}
581
607
@@ -600,7 +626,10 @@ bool remove_function_pointers(
600
626
only_remove_const_fps,
601
627
goto_functions);
602
628
603
- return rfp.remove_function_pointers (goto_program, function_id);
629
+ return rfp.remove_function_pointers (
630
+ goto_program,
631
+ function_id,
632
+ rfp.get_function_pointer_targets (goto_functions));
604
633
}
605
634
606
635
void remove_function_pointers (
@@ -618,7 +647,7 @@ void remove_function_pointers(
618
647
only_remove_const_fps,
619
648
goto_functions);
620
649
621
- rfp (goto_functions);
650
+ rfp (goto_functions, rfp. get_function_pointer_targets (goto_functions) );
622
651
}
623
652
624
653
void remove_function_pointers (message_handlert &_message_handler,
@@ -634,19 +663,28 @@ void remove_function_pointers(message_handlert &_message_handler,
634
663
only_remove_const_fps);
635
664
}
636
665
637
- possible_fp_targets_mapt get_function_pointer_targets (
638
- message_handlert &message_handler,
639
- goto_modelt &goto_model)
666
+ void remove_function_pointers (
667
+ message_handlert &_message_handler,
668
+ goto_modelt &goto_model,
669
+ const possible_fp_targets_mapt &target_map,
670
+ bool add_safety_assertion,
671
+ bool only_remove_const_fps)
640
672
{
641
673
remove_function_pointerst rfp (
642
- message_handler ,
674
+ _message_handler ,
643
675
goto_model.symbol_table ,
644
- false ,
645
- false ,
676
+ add_safety_assertion ,
677
+ only_remove_const_fps ,
646
678
goto_model.goto_functions );
647
679
680
+ rfp (goto_model.goto_functions , target_map);
681
+ }
682
+
683
+ possible_fp_targets_mapt
684
+ remove_function_pointerst::get_function_pointer_targets (
685
+ const goto_functionst &goto_functions)
686
+ {
648
687
possible_fp_targets_mapt target_map;
649
- const auto &goto_functions = goto_model.goto_functions ;
650
688
for (const auto &function_pair : goto_functions.function_map )
651
689
{
652
690
const auto &instructions = function_pair.second .body .instructions ;
@@ -671,6 +709,20 @@ possible_fp_targets_mapt get_function_pointer_targets(
671
709
return target_map;
672
710
}
673
711
712
+ possible_fp_targets_mapt get_function_pointer_targets (
713
+ message_handlert &message_handler,
714
+ goto_modelt &goto_model)
715
+ {
716
+ remove_function_pointerst rfp (
717
+ message_handler,
718
+ goto_model.symbol_table ,
719
+ false ,
720
+ false ,
721
+ goto_model.goto_functions );
722
+
723
+ return rfp.get_function_pointer_targets (goto_model.goto_functions );
724
+ }
725
+
674
726
goto_programt remove_function_pointerst::build_new_code (
675
727
const functionst &functions,
676
728
const code_function_callt &code,
0 commit comments