@@ -206,15 +206,26 @@ void parse_function_pointer_restriction_options_from_cmdline(
206
206
const cmdlinet &cmdline,
207
207
optionst &options)
208
208
{
209
- options.set_option (
210
- RESTRICT_FUNCTION_POINTER_OPT,
211
- cmdline.get_values (RESTRICT_FUNCTION_POINTER_OPT));
212
- options.set_option (
213
- RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT,
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));
209
+ if (cmdline.isset (RESTRICT_FUNCTION_POINTER_OPT))
210
+ {
211
+ options.set_option (
212
+ RESTRICT_FUNCTION_POINTER_OPT,
213
+ cmdline.get_values (RESTRICT_FUNCTION_POINTER_OPT));
214
+ }
215
+
216
+ if (cmdline.isset (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT))
217
+ {
218
+ options.set_option (
219
+ RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT,
220
+ cmdline.get_values (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT));
221
+ }
222
+
223
+ if (cmdline.isset (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT))
224
+ {
225
+ options.set_option (
226
+ RESTRICT_FUNCTION_POINTER_BY_NAME_OPT,
227
+ cmdline.get_values (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT));
228
+ }
218
229
}
219
230
220
231
namespace
@@ -240,10 +251,12 @@ merge_function_pointer_restrictions(
240
251
}
241
252
242
253
function_pointer_restrictionst::restrictionst
243
- parse_function_pointer_restrictions_from_command_line (
254
+ parse_function_pointer_restrictions (
244
255
const std::list<std::string> &restriction_opts,
245
256
const std::string &option_name)
246
257
{
258
+ const std::string option = " --" + option_name;
259
+
247
260
auto function_pointer_restrictions =
248
261
function_pointer_restrictionst::restrictionst{};
249
262
for (auto const &restriction_opt : restriction_opts)
@@ -258,21 +271,21 @@ parse_function_pointer_restrictions_from_command_line(
258
271
{
259
272
throw invalid_command_line_argument_exceptiont{
260
273
" couldn't find '/' in `" + restriction_opt + " '" ,
261
- " -- " RESTRICT_FUNCTION_POINTER_OPT ,
274
+ option ,
262
275
restriction_format_message};
263
276
}
264
277
if (pointer_name_end == restriction_opt.size ())
265
278
{
266
279
throw invalid_command_line_argument_exceptiont{
267
280
" couldn't find names of targets after '/' in `" + restriction_opt + " '" ,
268
- " -- " RESTRICT_FUNCTION_POINTER_OPT ,
281
+ option ,
269
282
restriction_format_message};
270
283
}
271
284
if (pointer_name_end == 0 )
272
285
{
273
286
throw invalid_command_line_argument_exceptiont{
274
287
" couldn't find target name before '/' in `" + restriction_opt + " '" ,
275
- " -- " RESTRICT_FUNCTION_POINTER_OPT };
288
+ option_name };
276
289
}
277
290
auto const pointer_name = restriction_opt.substr (0 , pointer_name_end);
278
291
auto const target_names_substring =
@@ -282,7 +295,7 @@ parse_function_pointer_restrictions_from_command_line(
282
295
{
283
296
throw invalid_command_line_argument_exceptiont{
284
297
" missing target list for function pointer restriction " + pointer_name,
285
- " -- " RESTRICT_FUNCTION_POINTER_OPT ,
298
+ option ,
286
299
restriction_format_message};
287
300
}
288
301
@@ -296,7 +309,7 @@ parse_function_pointer_restrictions_from_command_line(
296
309
throw invalid_command_line_argument_exceptiont (
297
310
" leading or trailing comma in restrictions for `" + pointer_name +
298
311
" '" ,
299
- " -- " RESTRICT_FUNCTION_POINTER_OPT ,
312
+ option ,
300
313
restriction_format_message);
301
314
}
302
315
}
@@ -307,12 +320,20 @@ parse_function_pointer_restrictions_from_command_line(
307
320
throw invalid_command_line_argument_exceptiont{
308
321
" function pointer restriction for `" + pointer_name +
309
322
" ' was specified twice" ,
310
- " -- " RESTRICT_FUNCTION_POINTER_OPT };
323
+ option };
311
324
};
312
325
}
313
326
return function_pointer_restrictions;
314
327
}
315
328
329
+ function_pointer_restrictionst::restrictionst
330
+ parse_function_pointer_restrictions_from_command_line (
331
+ const std::list<std::string> &restriction_opts)
332
+ {
333
+ return parse_function_pointer_restrictions (
334
+ restriction_opts, RESTRICT_FUNCTION_POINTER_OPT);
335
+ }
336
+
316
337
function_pointer_restrictionst::restrictionst
317
338
parse_function_pointer_restrictions_from_file (
318
339
const std::list<std::string> &filenames,
@@ -328,22 +349,84 @@ parse_function_pointer_restrictions_from_file(
328
349
}
329
350
return merged_restrictions;
330
351
}
352
+
353
+ function_pointer_restrictionst::restrictionst
354
+ get_function_pointer_by_name_restrictions (
355
+ const std::list<std::string> &restriction_name_opts,
356
+ const goto_modelt &goto_model)
357
+ {
358
+ function_pointer_restrictionst::restrictionst by_name_restrictions =
359
+ parse_function_pointer_restrictions (
360
+ restriction_name_opts, RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
361
+
362
+ function_pointer_restrictionst::restrictionst restrictions;
363
+ for (auto const &goto_function : goto_model.goto_functions .function_map )
364
+ {
365
+ for_each_function_call (
366
+ goto_function.second , [&](goto_programt::const_targett location) {
367
+ PRECONDITION (location->is_function_call ());
368
+ if (can_cast_expr<dereference_exprt>(
369
+ location->get_function_call ().function ()))
370
+ {
371
+ PRECONDITION (can_cast_expr<symbol_exprt>(
372
+ to_dereference_expr (location->get_function_call ().function ())
373
+ .pointer ()));
374
+ auto const &function_pointer_call_site = to_symbol_expr (
375
+ to_dereference_expr (location->get_function_call ().function ())
376
+ .pointer ());
377
+ auto const &body = goto_function.second .body ;
378
+ for (auto it = std::prev (location); it != body.instructions .end ();
379
+ ++it)
380
+ {
381
+ if (
382
+ it->is_assign () &&
383
+ it->get_assign ().lhs () == function_pointer_call_site &&
384
+ can_cast_expr<symbol_exprt>(it->get_assign ().rhs ()))
385
+ {
386
+ auto const &assign_rhs = to_symbol_expr (it->get_assign ().rhs ());
387
+ auto const restriction =
388
+ by_name_restrictions.find (assign_rhs.get_identifier ());
389
+ if (
390
+ restriction != by_name_restrictions.end () &&
391
+ restriction->first == assign_rhs.get_identifier ())
392
+ {
393
+ restrictions.emplace (
394
+ function_pointer_call_site.get_identifier (),
395
+ restriction->second );
396
+ }
397
+ }
398
+ }
399
+ }
400
+ });
401
+ }
402
+ return restrictions;
403
+ }
331
404
} // namespace
332
405
333
406
function_pointer_restrictionst function_pointer_restrictionst::from_options (
334
407
const optionst &options,
408
+ const goto_modelt &goto_model,
335
409
message_handlert &message_handler)
336
410
{
337
411
auto const restriction_opts =
338
412
options.get_list_option (RESTRICT_FUNCTION_POINTER_OPT);
339
413
auto const commandline_restrictions =
340
- parse_function_pointer_restrictions_from_command_line (
341
- restriction_opts, RESTRICT_FUNCTION_POINTER_OPT);
414
+ parse_function_pointer_restrictions_from_command_line (restriction_opts);
415
+
416
+ auto const restriction_file_opts =
417
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT);
342
418
auto const file_restrictions = parse_function_pointer_restrictions_from_file (
343
- options. get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT) ,
419
+ restriction_file_opts ,
344
420
message_handler);
345
- return {merge_function_pointer_restrictions (
346
- file_restrictions, commandline_restrictions)};
421
+
422
+ auto const restriction_name_opts =
423
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
424
+ auto const name_restrictions =
425
+ get_function_pointer_by_name_restrictions (
426
+ restriction_name_opts, goto_model);
427
+
428
+ return {merge_function_pointer_restrictions (commandline_restrictions,
429
+ merge_function_pointer_restrictions (file_restrictions, name_restrictions))};
347
430
}
348
431
349
432
function_pointer_restrictionst function_pointer_restrictionst::read_from_file (
@@ -415,60 +498,3 @@ void function_pointer_restrictionst::write_to_file(
415
498
}
416
499
function_pointer_restrictions_json.output (outFile);
417
500
}
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