@@ -238,15 +238,16 @@ function_pointer_restrictionst::merge_function_pointer_restrictions(
238
238
function_pointer_restrictionst::restrictionst
239
239
function_pointer_restrictionst::parse_function_pointer_restrictions (
240
240
const std::list<std::string> &restriction_opts,
241
- const std::string &option)
241
+ const std::string &option,
242
+ const goto_modelt &goto_model)
242
243
{
243
244
auto function_pointer_restrictions =
244
245
function_pointer_restrictionst::restrictionst{};
245
246
246
247
for (const std::string &restriction_opt : restriction_opts)
247
248
{
248
249
const auto restriction =
249
- parse_function_pointer_restriction (restriction_opt, option);
250
+ parse_function_pointer_restriction (restriction_opt, option, goto_model );
250
251
251
252
const bool inserted = function_pointer_restrictions
252
253
.emplace (restriction.first , restriction.second )
@@ -265,10 +266,11 @@ function_pointer_restrictionst::parse_function_pointer_restrictions(
265
266
266
267
function_pointer_restrictionst::restrictionst function_pointer_restrictionst::
267
268
parse_function_pointer_restrictions_from_command_line (
268
- const std::list<std::string> &restriction_opts)
269
+ const std::list<std::string> &restriction_opts,
270
+ const goto_modelt &goto_model)
269
271
{
270
272
return parse_function_pointer_restrictions (
271
- restriction_opts, " --" RESTRICT_FUNCTION_POINTER_OPT);
273
+ restriction_opts, " --" RESTRICT_FUNCTION_POINTER_OPT, goto_model );
272
274
}
273
275
274
276
function_pointer_restrictionst::restrictionst
@@ -292,7 +294,8 @@ function_pointer_restrictionst::parse_function_pointer_restrictions_from_file(
292
294
function_pointer_restrictionst::restrictiont
293
295
function_pointer_restrictionst::parse_function_pointer_restriction (
294
296
const std::string &restriction_opt,
295
- const std::string &option)
297
+ const std::string &option,
298
+ const goto_modelt &goto_model)
296
299
{
297
300
// the format for restrictions is <pointer_name>/<target[,more_targets]*>
298
301
// exactly one pointer and at least one target
@@ -321,7 +324,50 @@ function_pointer_restrictionst::parse_function_pointer_restriction(
321
324
" couldn't find target name before '/' in `" + restriction_opt + " '" };
322
325
}
323
326
324
- auto const pointer_name = restriction_opt.substr (0 , pointer_name_end);
327
+ auto pointer_name = restriction_opt.substr (0 , pointer_name_end);
328
+ const auto last_dot = pointer_name.rfind (' .' );
329
+ if (
330
+ last_dot != std::string::npos && last_dot + 1 != pointer_name.size () &&
331
+ !isdigit (pointer_name[last_dot + 1 ]))
332
+ {
333
+ const auto function_id = pointer_name.substr (0 , last_dot);
334
+ const auto label = pointer_name.substr (last_dot + 1 );
335
+
336
+ bool found = false ;
337
+ const auto it = goto_model.goto_functions .function_map .find (function_id);
338
+ if (it != goto_model.goto_functions .function_map .end ())
339
+ {
340
+ for (const auto &instruction : it->second .body .instructions )
341
+ {
342
+ if (!instruction.is_function_call ())
343
+ continue ;
344
+
345
+ const auto &called_function = instruction.call_function ();
346
+ if (called_function.id () != ID_dereference)
347
+ continue ;
348
+
349
+ if (
350
+ std::find (
351
+ instruction.labels .begin (), instruction.labels .end (), label) !=
352
+ instruction.labels .end ())
353
+ {
354
+ auto const &called_function_pointer =
355
+ to_dereference_expr (called_function).pointer ();
356
+ pointer_name =
357
+ id2string (to_symbol_expr (called_function_pointer).get_identifier ());
358
+ found = true ;
359
+ break ;
360
+ }
361
+ }
362
+ }
363
+ if (!found)
364
+ {
365
+ throw invalid_restriction_exceptiont{" non-existent pointer name " +
366
+ pointer_name,
367
+ restriction_format_message};
368
+ }
369
+ }
370
+
325
371
auto const target_names_substring =
326
372
restriction_opt.substr (pointer_name_end + 1 );
327
373
auto const target_name_strings = split_string (target_names_substring, ' ,' );
@@ -405,7 +451,8 @@ function_pointer_restrictionst function_pointer_restrictionst::from_options(
405
451
try
406
452
{
407
453
commandline_restrictions =
408
- parse_function_pointer_restrictions_from_command_line (restriction_opts);
454
+ parse_function_pointer_restrictions_from_command_line (
455
+ restriction_opts, goto_model);
409
456
typecheck_function_pointer_restrictions (
410
457
goto_model, commandline_restrictions);
411
458
}
@@ -549,7 +596,9 @@ function_pointer_restrictionst::get_function_pointer_by_name_restrictions(
549
596
{
550
597
function_pointer_restrictionst::restrictionst by_name_restrictions =
551
598
parse_function_pointer_restrictions (
552
- restriction_name_opts, " --" RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
599
+ restriction_name_opts,
600
+ " --" RESTRICT_FUNCTION_POINTER_BY_NAME_OPT,
601
+ goto_model);
553
602
554
603
function_pointer_restrictionst::restrictionst restrictions;
555
604
for (auto const &goto_function : goto_model.goto_functions .function_map )
0 commit comments