@@ -108,12 +108,13 @@ source_locationt make_function_pointer_restriction_assertion_source_location(
108
108
return source_location;
109
109
}
110
110
111
- template <typename Handler>
112
- void for_each_function_call (goto_functiont &goto_function, Handler handler)
111
+ template <typename Handler, typename GotoFunctionT >
112
+ void for_each_function_call (GotoFunctionT & &goto_function, Handler handler)
113
113
{
114
+ using targett = decltype (goto_function.body .instructions .begin ());
114
115
for_each_instruction_if (
115
116
goto_function,
116
- [](goto_programt:: targett target) { return target->is_function_call (); },
117
+ [](targett target) { return target->is_function_call (); },
117
118
handler);
118
119
}
119
120
} // namespace
@@ -211,6 +212,9 @@ void parse_function_pointer_restriction_options_from_cmdline(
211
212
options.set_option (
212
213
RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT,
213
214
cmdline.get_values (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT));
215
+ options.set_option (
216
+ RESTRICT_FUNCTION_POINTER_BY_NAME_OPT,
217
+ cmdline.get_values (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT));
214
218
}
215
219
216
220
namespace
@@ -237,7 +241,8 @@ merge_function_pointer_restrictions(
237
241
238
242
function_pointer_restrictionst::restrictionst
239
243
parse_function_pointer_restrictions_from_command_line (
240
- const std::list<std::string> &restriction_opts)
244
+ const std::list<std::string> &restriction_opts,
245
+ const std::string &option_name)
241
246
{
242
247
auto function_pointer_restrictions =
243
248
function_pointer_restrictionst::restrictionst{};
@@ -332,7 +337,8 @@ function_pointer_restrictionst function_pointer_restrictionst::from_options(
332
337
auto const restriction_opts =
333
338
options.get_list_option (RESTRICT_FUNCTION_POINTER_OPT);
334
339
auto const commandline_restrictions =
335
- parse_function_pointer_restrictions_from_command_line (restriction_opts);
340
+ parse_function_pointer_restrictions_from_command_line (
341
+ restriction_opts, RESTRICT_FUNCTION_POINTER_OPT);
336
342
auto const file_restrictions = parse_function_pointer_restrictions_from_file (
337
343
options.get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT),
338
344
message_handler);
@@ -409,3 +415,60 @@ void function_pointer_restrictionst::write_to_file(
409
415
}
410
416
function_pointer_restrictions_json.output (outFile);
411
417
}
418
+ function_pointer_restrictionst function_pointer_restrictionst::merge (
419
+ const function_pointer_restrictionst &other) const
420
+ {
421
+ return function_pointer_restrictionst{
422
+ merge_function_pointer_restrictions (restrictions, other.restrictions )};
423
+ }
424
+
425
+ function_pointer_restrictionst get_function_pointer_by_name_restrictions (
426
+ const goto_modelt &goto_model,
427
+ const optionst &options)
428
+ {
429
+ function_pointer_restrictionst::restrictionst by_name_restrictions =
430
+ parse_function_pointer_restrictions_from_command_line (
431
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT),
432
+ RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
433
+ function_pointer_restrictionst::restrictionst restrictions;
434
+ for (auto const &goto_function : goto_model.goto_functions .function_map )
435
+ {
436
+ for_each_function_call (
437
+ goto_function.second , [&](goto_programt::const_targett location) {
438
+ PRECONDITION (location->is_function_call ());
439
+ if (can_cast_expr<dereference_exprt>(
440
+ location->get_function_call ().function ()))
441
+ {
442
+ PRECONDITION (can_cast_expr<symbol_exprt>(
443
+ to_dereference_expr (location->get_function_call ().function ())
444
+ .pointer ()));
445
+ auto const &function_pointer_call_site = to_symbol_expr (
446
+ to_dereference_expr (location->get_function_call ().function ())
447
+ .pointer ());
448
+ auto const &body = goto_function.second .body ;
449
+ for (auto it = std::prev (location); it != body.instructions .end ();
450
+ ++it)
451
+ {
452
+ if (
453
+ it->is_assign () &&
454
+ it->get_assign ().lhs () == function_pointer_call_site &&
455
+ can_cast_expr<symbol_exprt>(it->get_assign ().rhs ()))
456
+ {
457
+ auto const &assign_rhs = to_symbol_expr (it->get_assign ().rhs ());
458
+ auto const restriction =
459
+ by_name_restrictions.find (assign_rhs.get_identifier ());
460
+ if (
461
+ restriction != by_name_restrictions.end () &&
462
+ restriction->first == assign_rhs.get_identifier ())
463
+ {
464
+ restrictions.emplace (
465
+ function_pointer_call_site.get_identifier (),
466
+ restriction->second );
467
+ }
468
+ }
469
+ }
470
+ }
471
+ });
472
+ }
473
+ return function_pointer_restrictionst{restrictions};
474
+ }
0 commit comments