@@ -104,12 +104,13 @@ source_locationt make_function_pointer_restriction_assertion_source_location(
104
104
return source_location;
105
105
}
106
106
107
- template <typename Handler>
108
- void for_each_function_call (goto_functiont &goto_function, Handler handler)
107
+ template <typename Handler, typename GotoFunctionT >
108
+ void for_each_function_call (GotoFunctionT & &goto_function, Handler handler)
109
109
{
110
+ using targett = decltype (goto_function.body .instructions .begin ());
110
111
for_each_instruction_if (
111
112
goto_function,
112
- [](goto_programt:: targett target) { return target->is_function_call (); },
113
+ [](targett target) { return target->is_function_call (); },
113
114
handler);
114
115
}
115
116
@@ -220,6 +221,9 @@ void parse_function_pointer_restriction_options_from_cmdline(
220
221
options.set_option (
221
222
RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT,
222
223
cmdline.get_values (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT));
224
+ options.set_option (
225
+ RESTRICT_FUNCTION_POINTER_BY_NAME_OPT,
226
+ cmdline.get_values (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT));
223
227
}
224
228
225
229
function_pointer_restrictionst::restrictionst
@@ -244,9 +248,11 @@ function_pointer_restrictionst::merge_function_pointer_restrictions(
244
248
return result;
245
249
}
246
250
247
- function_pointer_restrictionst::restrictionst function_pointer_restrictionst::
248
- parse_function_pointer_restrictions_from_command_line (
249
- const std::list<std::string> &restriction_opts)
251
+ function_pointer_restrictionst::restrictionst
252
+ function_pointer_restrictionst::
253
+ parse_function_pointer_restrictions_from_command_line (
254
+ const std::list<std::string> &restriction_opts,
255
+ const std::string &option_name)
250
256
{
251
257
auto function_pointer_restrictions =
252
258
function_pointer_restrictionst::restrictionst{};
@@ -361,7 +367,8 @@ function_pointer_restrictionst function_pointer_restrictionst::from_options(
361
367
auto const restriction_opts =
362
368
options.get_list_option (RESTRICT_FUNCTION_POINTER_OPT);
363
369
auto const commandline_restrictions =
364
- parse_function_pointer_restrictions_from_command_line (restriction_opts);
370
+ parse_function_pointer_restrictions_from_command_line (
371
+ restriction_opts, RESTRICT_FUNCTION_POINTER_OPT);
365
372
auto const file_restrictions = parse_function_pointer_restrictions_from_file (
366
373
options.get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT),
367
374
message_handler);
@@ -459,3 +466,61 @@ void function_pointer_restrictionst::write_to_file(
459
466
460
467
function_pointer_restrictions_json.output (outFile);
461
468
}
469
+ function_pointer_restrictionst function_pointer_restrictionst::merge (
470
+ const function_pointer_restrictionst &other) const
471
+ {
472
+ return function_pointer_restrictionst{
473
+ merge_function_pointer_restrictions (restrictions, other.restrictions )};
474
+ }
475
+
476
+ function_pointer_restrictionst get_function_pointer_by_name_restrictions (
477
+ const goto_modelt &goto_model,
478
+ const optionst &options)
479
+ {
480
+ function_pointer_restrictionst::restrictionst by_name_restrictions =
481
+ function_pointer_restrictionst::
482
+ parse_function_pointer_restrictions_from_command_line (
483
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT),
484
+ RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
485
+ function_pointer_restrictionst::restrictionst restrictions;
486
+ for (auto const &goto_function : goto_model.goto_functions .function_map )
487
+ {
488
+ for_each_function_call (
489
+ goto_function.second , [&](goto_programt::const_targett location) {
490
+ PRECONDITION (location->is_function_call ());
491
+ if (can_cast_expr<dereference_exprt>(
492
+ location->get_function_call ().function ()))
493
+ {
494
+ PRECONDITION (can_cast_expr<symbol_exprt>(
495
+ to_dereference_expr (location->get_function_call ().function ())
496
+ .pointer ()));
497
+ auto const &function_pointer_call_site = to_symbol_expr (
498
+ to_dereference_expr (location->get_function_call ().function ())
499
+ .pointer ());
500
+ auto const &body = goto_function.second .body ;
501
+ for (auto it = std::prev (location); it != body.instructions .end ();
502
+ ++it)
503
+ {
504
+ if (
505
+ it->is_assign () &&
506
+ it->get_assign ().lhs () == function_pointer_call_site &&
507
+ can_cast_expr<symbol_exprt>(it->get_assign ().rhs ()))
508
+ {
509
+ auto const &assign_rhs = to_symbol_expr (it->get_assign ().rhs ());
510
+ auto const restriction =
511
+ by_name_restrictions.find (assign_rhs.get_identifier ());
512
+ if (
513
+ restriction != by_name_restrictions.end () &&
514
+ restriction->first == assign_rhs.get_identifier ())
515
+ {
516
+ restrictions.emplace (
517
+ function_pointer_call_site.get_identifier (),
518
+ restriction->second );
519
+ }
520
+ }
521
+ }
522
+ }
523
+ });
524
+ }
525
+ return function_pointer_restrictionst{restrictions};
526
+ }
0 commit comments