@@ -419,95 +419,22 @@ void remove_function_pointerst::remove_function_pointer(
419
419
const irep_idt &function_id,
420
420
goto_programt::targett target)
421
421
{
422
- const code_function_callt &code = target->get_function_call ();
423
-
424
- const auto &function = to_dereference_expr (code.function ());
425
-
426
- // this better have the right type
427
- code_typet call_type=to_code_type (function.type ());
428
-
429
- // refine the type in case the forward declaration was incomplete
430
- if (call_type.has_ellipsis () &&
431
- call_type.parameters ().empty ())
432
- {
433
- call_type.remove_ellipsis ();
434
- forall_expr (it, code.arguments ())
435
- call_type.parameters ().push_back (
436
- code_typet::parametert (it->type ()));
437
- }
422
+ goto_programt::const_targett const_target = target;
423
+ const auto candidates_pair =
424
+ get_function_pointer_targets (goto_program, const_target);
425
+ const auto &functions = candidates_pair.first ;
426
+ const bool const_functions_removal_success = candidates_pair.second ;
438
427
439
- bool found_functions;
440
-
441
- const exprt &pointer = function.pointer ();
442
- remove_const_function_pointerst::functionst functions;
443
- does_remove_constt const_removal_check (goto_program, ns);
444
- const auto does_remove_const = const_removal_check ();
445
- if (does_remove_const.first )
446
- {
447
- log.warning ().source_location = does_remove_const.second ;
448
- log.warning () << " cast from const to non-const pointer found, "
449
- << " only worst case function pointer removal will be done."
450
- << messaget::eom;
451
- found_functions=false ;
452
- }
453
- else
428
+ if (const_functions_removal_success && functions.size () == 1 )
454
429
{
455
- remove_const_function_pointerst fpr (
456
- log.get_message_handler (), ns, symbol_table);
457
-
458
- found_functions=fpr (pointer, functions);
459
-
460
- // if found_functions is false, functions should be empty
461
- // however, it is possible for found_functions to be true and functions
462
- // to be empty (this happens if the pointer can only resolve to the null
463
- // pointer)
464
- CHECK_RETURN (found_functions || functions.empty ());
465
-
466
- if (functions.size ()==1 )
467
- {
468
- auto call = target->get_function_call ();
469
- call.function () = *functions.cbegin ();
470
- target->set_function_call (call);
471
- return ;
472
- }
430
+ auto call = target->get_function_call ();
431
+ call.function () = *functions.cbegin ();
432
+ target->set_function_call (call);
473
433
}
474
-
475
- if (!found_functions)
434
+ else if (!const_functions_removal_success && !only_resolve_const_fps)
476
435
{
477
- if (only_resolve_const_fps)
478
- {
479
- // If this mode is enabled, we only remove function pointers
480
- // that we can resolve either to an exact function, or an exact subset
481
- // (e.g. a variable index in a constant array).
482
- // Since we haven't found functions, we would now resort to
483
- // replacing the function pointer with any function with a valid signature
484
- // Since we don't want to do that, we abort.
485
- return ;
486
- }
487
-
488
- bool return_value_used=code.lhs ().is_not_nil ();
489
-
490
- // get all type-compatible functions
491
- // whose address is ever taken
492
- for (const auto &t : type_map)
493
- {
494
- // address taken?
495
- if (address_taken.find (t.first )==address_taken.end ())
496
- continue ;
497
-
498
- // type-compatible?
499
- if (!is_type_compatible (return_value_used, call_type, t.second ))
500
- continue ;
501
-
502
- if (t.first ==" pthread_mutex_cleanup" )
503
- continue ;
504
-
505
- symbol_exprt expr (t.first , t.second );
506
- functions.insert (expr);
507
- }
436
+ remove_function_pointer (goto_program, function_id, target, functions);
508
437
}
509
-
510
- remove_function_pointer (goto_program, function_id, target, functions);
511
438
}
512
439
513
440
void remove_function_pointerst::remove_function_pointer (
0 commit comments