@@ -94,9 +94,42 @@ class remove_function_pointerst
94
94
95
95
// Internal variables for communication between function pointer collection
96
96
// 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
+ }
100
133
101
134
// / Replace a call to a dynamic function at location
102
135
// / target in the given goto-program by determining
@@ -357,21 +390,22 @@ code_typet remove_function_pointerst::refine_call_type(
357
390
void remove_function_pointerst::try_remove_const_fp (
358
391
const goto_programt &goto_program,
359
392
functionst &functions,
360
- const exprt &pointer)
393
+ const exprt &pointer,
394
+ const irep_idt &callee_id)
361
395
{
362
396
PRECONDITION (functions.empty ());
363
397
364
398
does_remove_constt const_removal_check (goto_program, ns);
365
399
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 ) ;
367
401
368
- if (does_remove_const_success )
402
+ if (does_remove_const. first )
369
403
{
370
404
log.warning ().source_location = does_remove_const.second ;
371
405
log.warning () << " cast from const to non-const pointer found, "
372
406
<< " only worst case function pointer removal will be done."
373
407
<< messaget::eom;
374
- remove_const_found_functions = false ;
408
+ set_remove_const_found_functions (callee_id, false ) ;
375
409
}
376
410
else
377
411
{
@@ -382,8 +416,9 @@ void remove_function_pointerst::try_remove_const_fp(
382
416
// however, it is possible for found_functions to be true and functions
383
417
// to be empty (this happens if the pointer can only resolve to the null
384
418
// 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 ());
387
422
}
388
423
}
389
424
@@ -415,13 +450,14 @@ remove_function_pointerst::get_function_pointer_targets(
415
450
const auto &refined_call_type = refine_call_type (function.type (), code);
416
451
417
452
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);
419
455
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 ) ;
422
458
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)
425
461
{
426
462
// get all type-compatible functions
427
463
// whose address is ever taken
@@ -459,13 +495,15 @@ void remove_function_pointerst::remove_function_pointer(
459
495
const auto functions =
460
496
get_function_pointer_targets (goto_program, const_target);
461
497
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))
463
500
{
464
501
auto call = target->get_function_call ();
465
502
call.function () = *functions.cbegin ();
466
503
target->set_function_call (call);
467
504
}
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)
469
507
{
470
508
// If this mode is enabled, we only remove function pointers
471
509
// 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(
621
659
target->is_function_call () &&
622
660
target->get_function_call ().function ().id () == ID_dereference)
623
661
{
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
+ }
631
670
}
632
671
}
633
672
}
0 commit comments