@@ -38,23 +38,33 @@ 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
66
// / \param functions: The set of functions to consider
57
- void remove_function_pointer (
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,
@@ -66,7 +76,7 @@ class remove_function_pointerst
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_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
+
81
98
protected:
82
99
messaget log;
83
100
const namespacet ns;
@@ -104,10 +121,12 @@ class remove_function_pointerst
104
121
// / \param goto_program: The goto program that contains target
105
122
// / \param function_id: Name of function containing the target
106
123
// / \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 (
108
126
goto_programt &goto_program,
109
127
const irep_idt &function_id,
110
- goto_programt::targett target);
128
+ goto_programt::targett target,
129
+ const functionst &functions);
111
130
112
131
std::unordered_set<irep_idt> address_taken;
113
132
@@ -384,11 +403,11 @@ void remove_function_pointerst::try_remove_const_fp(
384
403
385
404
remove_function_pointerst::functionst
386
405
remove_function_pointerst::get_function_pointer_targets (
387
- const goto_modelt &goto_model ,
406
+ const goto_functionst &goto_functions ,
388
407
goto_programt::const_targett &call_site)
389
408
{
390
409
functionst functions;
391
- for (const auto &function_pair : goto_model. goto_functions .function_map )
410
+ for (const auto &function_pair : goto_functions.function_map )
392
411
{
393
412
const auto &function_body = function_pair.second .body ;
394
413
const auto &candidates =
@@ -445,15 +464,12 @@ remove_function_pointerst::get_function_pointer_targets(
445
464
return functions;
446
465
}
447
466
448
- void remove_function_pointerst::remove_function_pointer (
467
+ void remove_function_pointerst::remove_function_pointer_const (
449
468
goto_programt &goto_program,
450
469
const irep_idt &function_id,
451
- goto_programt::targett target)
470
+ goto_programt::targett target,
471
+ const functionst &functions)
452
472
{
453
- goto_programt::const_targett const_target = target;
454
- const auto functions =
455
- get_function_pointer_targets (goto_program, const_target);
456
-
457
473
if (only_remove_const_function_pointers_called)
458
474
{
459
475
auto call = target->get_function_call ();
@@ -468,11 +484,12 @@ void remove_function_pointerst::remove_function_pointer(
468
484
// Since we haven't found functions, we would now resort to
469
485
// replacing the function pointer with any function with a valid signature
470
486
// 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);
472
489
}
473
490
}
474
491
475
- void remove_function_pointerst::remove_function_pointer (
492
+ void remove_function_pointerst::remove_function_pointer_non_const (
476
493
goto_programt &goto_program,
477
494
const irep_idt &function_id,
478
495
goto_programt::targett target,
@@ -501,7 +518,8 @@ void remove_function_pointerst::remove_function_pointer(
501
518
502
519
bool remove_function_pointerst::remove_function_pointers (
503
520
goto_programt &goto_program,
504
- const irep_idt &function_id)
521
+ const irep_idt &function_id,
522
+ const possible_fp_targets_mapt &target_map)
505
523
{
506
524
bool did_something=false ;
507
525
@@ -512,7 +530,8 @@ bool remove_function_pointerst::remove_function_pointers(
512
530
513
531
if (code.function ().id ()==ID_dereference)
514
532
{
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));
516
535
did_something=true ;
517
536
}
518
537
}
@@ -523,7 +542,9 @@ bool remove_function_pointerst::remove_function_pointers(
523
542
return did_something;
524
543
}
525
544
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)
527
548
{
528
549
bool did_something=false ;
529
550
@@ -534,7 +555,7 @@ void remove_function_pointerst::operator()(goto_functionst &functions)
534
555
{
535
556
goto_programt &goto_program=f_it->second .body ;
536
557
537
- if (remove_function_pointers (goto_program, f_it->first ))
558
+ if (remove_function_pointers (goto_program, f_it->first , target_map ))
538
559
did_something=true ;
539
560
}
540
561
@@ -559,7 +580,10 @@ bool remove_function_pointers(
559
580
only_remove_const_fps,
560
581
goto_functions);
561
582
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));
563
587
}
564
588
565
589
void remove_function_pointers (
@@ -577,7 +601,7 @@ void remove_function_pointers(
577
601
only_remove_const_fps,
578
602
goto_functions);
579
603
580
- rfp (goto_functions);
604
+ rfp (goto_functions, rfp. get_function_pointer_targets (goto_functions) );
581
605
}
582
606
583
607
void remove_function_pointers (message_handlert &_message_handler,
@@ -593,19 +617,28 @@ void remove_function_pointers(message_handlert &_message_handler,
593
617
only_remove_const_fps);
594
618
}
595
619
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)
599
626
{
600
627
remove_function_pointerst rfp (
601
- message_handler ,
628
+ _message_handler ,
602
629
goto_model.symbol_table ,
603
- false ,
604
- false ,
630
+ add_safety_assertion ,
631
+ only_remove_const_fps ,
605
632
goto_model.goto_functions );
606
633
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
+ {
607
641
possible_fp_targets_mapt target_map;
608
- const auto &goto_functions = goto_model.goto_functions ;
609
642
for (const auto &function_pair : goto_functions.function_map )
610
643
{
611
644
const auto &instructions = function_pair.second .body .instructions ;
@@ -622,13 +655,27 @@ possible_fp_targets_mapt get_function_pointer_targets(
622
655
.pointer ())
623
656
.get_identifier ();
624
657
target_map.emplace (
625
- function_id, rfp. get_function_pointer_targets (goto_model , target));
658
+ function_id, get_function_pointer_targets (goto_functions , target));
626
659
}
627
660
}
628
661
}
629
662
return target_map;
630
663
}
631
664
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
+
632
679
goto_programt remove_function_pointerst::build_new_code (
633
680
const functionst &functions,
634
681
const code_function_callt &code,
0 commit comments