@@ -20,66 +20,6 @@ Author: Diffblue Ltd.
20
20
21
21
namespace
22
22
{
23
- void typecheck_function_pointer_restrictions (
24
- const goto_modelt &goto_model,
25
- const function_pointer_restrictionst &restrictions)
26
- {
27
- const std::string options =
28
- " --" RESTRICT_FUNCTION_POINTER_OPT " /"
29
- " --" RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT " /"
30
- " --" RESTRICT_FUNCTION_POINTER_BY_NAME_OPT;
31
-
32
- for (auto const &restriction : restrictions.restrictions )
33
- {
34
- auto const function_pointer_sym =
35
- goto_model.symbol_table .lookup (restriction.first );
36
- if (function_pointer_sym == nullptr )
37
- {
38
- throw invalid_command_line_argument_exceptiont{
39
- id2string (restriction.first ) + " not found in the symbol table" ,
40
- options};
41
- }
42
- auto const &function_pointer_type = function_pointer_sym->type ;
43
- if (function_pointer_type.id () != ID_pointer)
44
- {
45
- throw invalid_command_line_argument_exceptiont{
46
- " not a function pointer: " + id2string (restriction.first ),
47
- options};
48
- }
49
- auto const &function_type =
50
- to_pointer_type (function_pointer_type).subtype ();
51
- if (function_type.id () != ID_code)
52
- {
53
- throw invalid_command_line_argument_exceptiont{
54
- " not a function pointer: " + id2string (restriction.first ),
55
- options};
56
- }
57
- auto const &ns = namespacet{goto_model.symbol_table };
58
- for (auto const &function_pointer_target : restriction.second )
59
- {
60
- auto const function_pointer_target_sym =
61
- goto_model.symbol_table .lookup (function_pointer_target);
62
- if (function_pointer_target_sym == nullptr )
63
- {
64
- throw invalid_command_line_argument_exceptiont{
65
- " symbol not found: " + id2string (function_pointer_target),
66
- options};
67
- }
68
- auto const &function_pointer_target_type =
69
- function_pointer_target_sym->type ;
70
- if (function_type != function_pointer_target_type)
71
- {
72
- throw invalid_command_line_argument_exceptiont{
73
- " type mismatch: `" + id2string (restriction.first ) + " ' points to `" +
74
- type2c (function_type, ns) + " ', but restriction `" +
75
- id2string (function_pointer_target) + " ' has type `" +
76
- type2c (function_pointer_target_type, ns) + " '" ,
77
- options};
78
- }
79
- }
80
- }
81
- }
82
-
83
23
source_locationt make_function_pointer_restriction_assertion_source_location (
84
24
source_locationt source_location,
85
25
const function_pointer_restrictionst::restrictiont restriction)
@@ -200,12 +140,82 @@ void restrict_function_pointer(
200
140
}
201
141
} // namespace
202
142
143
+ function_pointer_restrictionst::invalid_restriction_exceptiont::
144
+ invalid_restriction_exceptiont (std::string reason, std::string correct_format)
145
+ : reason(std::move(reason)), correct_format(std::move(correct_format))
146
+ {
147
+ }
148
+
149
+ std::string
150
+ function_pointer_restrictionst::invalid_restriction_exceptiont::what () const
151
+ {
152
+ std::string res;
153
+
154
+ res += " Invalid restriction" ;
155
+ res += " \n Reason: " + reason;
156
+
157
+ if (!correct_format.empty ())
158
+ {
159
+ res += " \n Format: " + correct_format;
160
+ }
161
+
162
+ return res;
163
+ }
164
+
165
+ void function_pointer_restrictionst::typecheck_function_pointer_restrictions (
166
+ const goto_modelt &goto_model,
167
+ const function_pointer_restrictionst::restrictionst &restrictions)
168
+ {
169
+ for (auto const &restriction : restrictions)
170
+ {
171
+ auto const function_pointer_sym =
172
+ goto_model.symbol_table .lookup (restriction.first );
173
+ if (function_pointer_sym == nullptr )
174
+ {
175
+ throw invalid_restriction_exceptiont{id2string (restriction.first ) +
176
+ " not found in the symbol table" };
177
+ }
178
+ auto const &function_pointer_type = function_pointer_sym->type ;
179
+ if (function_pointer_type.id () != ID_pointer)
180
+ {
181
+ throw invalid_restriction_exceptiont{" not a function pointer: " +
182
+ id2string (restriction.first )};
183
+ }
184
+ auto const &function_type =
185
+ to_pointer_type (function_pointer_type).subtype ();
186
+ if (function_type.id () != ID_code)
187
+ {
188
+ throw invalid_restriction_exceptiont{" not a function pointer: " +
189
+ id2string (restriction.first )};
190
+ }
191
+ auto const &ns = namespacet{goto_model.symbol_table };
192
+ for (auto const &function_pointer_target : restriction.second )
193
+ {
194
+ auto const function_pointer_target_sym =
195
+ goto_model.symbol_table .lookup (function_pointer_target);
196
+ if (function_pointer_target_sym == nullptr )
197
+ {
198
+ throw invalid_restriction_exceptiont{
199
+ " symbol not found: " + id2string (function_pointer_target)};
200
+ }
201
+ auto const &function_pointer_target_type =
202
+ function_pointer_target_sym->type ;
203
+ if (function_type != function_pointer_target_type)
204
+ {
205
+ throw invalid_restriction_exceptiont{
206
+ " type mismatch: `" + id2string (restriction.first ) + " ' points to `" +
207
+ type2c (function_type, ns) + " ', but restriction `" +
208
+ id2string (function_pointer_target) + " ' has type `" +
209
+ type2c (function_pointer_target_type, ns) + " '" };
210
+ }
211
+ }
212
+ }
213
+ }
214
+
203
215
void restrict_function_pointers (
204
216
goto_modelt &goto_model,
205
217
const function_pointer_restrictionst &restrictions)
206
218
{
207
- typecheck_function_pointer_restrictions (goto_model, restrictions);
208
-
209
219
for (auto &function_item : goto_model.goto_functions .function_map )
210
220
{
211
221
goto_functiont &goto_function = function_item.second ;
@@ -283,24 +293,21 @@ function_pointer_restrictionst::parse_function_pointer_restrictions(
283
293
284
294
if (!inserted)
285
295
{
286
- throw invalid_command_line_argument_exceptiont {
296
+ throw invalid_restriction_exceptiont {
287
297
" function pointer restriction for `" + id2string (restriction.first ) +
288
- " ' was specified twice" ,
289
- option};
298
+ " ' was specified twice" };
290
299
}
291
300
}
292
301
293
302
return function_pointer_restrictions;
294
303
}
295
304
296
- function_pointer_restrictionst::restrictionst
297
- function_pointer_restrictionst::
298
- parse_function_pointer_restrictions_from_command_line (
299
- const std::list<std::string> &restriction_opts)
305
+ function_pointer_restrictionst::restrictionst function_pointer_restrictionst::
306
+ parse_function_pointer_restrictions_from_command_line (
307
+ const std::list<std::string> &restriction_opts)
300
308
{
301
309
return parse_function_pointer_restrictions (
302
- restriction_opts,
303
- " --" RESTRICT_FUNCTION_POINTER_OPT);
310
+ restriction_opts, " --" RESTRICT_FUNCTION_POINTER_OPT);
304
311
}
305
312
306
313
function_pointer_restrictionst::restrictionst
@@ -335,25 +342,22 @@ function_pointer_restrictionst::parse_function_pointer_restriction(
335
342
336
343
if (pointer_name_end == std::string::npos)
337
344
{
338
- throw invalid_command_line_argument_exceptiont{
339
- " couldn't find '/' in `" + restriction_opt + " '" ,
340
- option,
341
- restriction_format_message};
345
+ throw invalid_restriction_exceptiont{" couldn't find '/' in `" +
346
+ restriction_opt + " '" ,
347
+ restriction_format_message};
342
348
}
343
349
344
350
if (pointer_name_end == restriction_opt.size ())
345
351
{
346
- throw invalid_command_line_argument_exceptiont {
352
+ throw invalid_restriction_exceptiont {
347
353
" couldn't find names of targets after '/' in `" + restriction_opt + " '" ,
348
- option,
349
354
restriction_format_message};
350
355
}
351
356
352
357
if (pointer_name_end == 0 )
353
358
{
354
- throw invalid_command_line_argument_exceptiont{
355
- " couldn't find target name before '/' in `" + restriction_opt + " '" ,
356
- option};
359
+ throw invalid_restriction_exceptiont{
360
+ " couldn't find target name before '/' in `" + restriction_opt + " '" };
357
361
}
358
362
359
363
auto const pointer_name = restriction_opt.substr (0 , pointer_name_end);
@@ -363,9 +367,8 @@ function_pointer_restrictionst::parse_function_pointer_restriction(
363
367
364
368
if (target_name_strings.size () == 1 && target_name_strings[0 ].empty ())
365
369
{
366
- throw invalid_command_line_argument_exceptiont {
370
+ throw invalid_restriction_exceptiont {
367
371
" missing target list for function pointer restriction " + pointer_name,
368
- option,
369
372
restriction_format_message};
370
373
}
371
374
@@ -376,9 +379,8 @@ function_pointer_restrictionst::parse_function_pointer_restriction(
376
379
{
377
380
if (target_name == ID_empty_string)
378
381
{
379
- throw invalid_command_line_argument_exceptiont (
382
+ throw invalid_restriction_exceptiont (
380
383
" leading or trailing comma in restrictions for `" + pointer_name + " '" ,
381
- option,
382
384
restriction_format_message);
383
385
}
384
386
}
@@ -426,7 +428,7 @@ function_pointer_restrictionst::get_by_name_restriction(
426
428
{
427
429
return optionalt<function_pointer_restrictionst::restrictiont>(
428
430
std::make_pair (
429
- function_pointer_call_site.get_identifier (), restriction->second ));
431
+ function_pointer_call_site.get_identifier (), restriction->second ));
430
432
}
431
433
432
434
return {};
@@ -439,18 +441,49 @@ function_pointer_restrictionst function_pointer_restrictionst::from_options(
439
441
{
440
442
auto const restriction_opts =
441
443
options.get_list_option (RESTRICT_FUNCTION_POINTER_OPT);
442
- auto const commandline_restrictions =
443
- parse_function_pointer_restrictions_from_command_line (restriction_opts);
444
444
445
- auto const restriction_file_opts =
446
- options.get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT);
447
- auto const file_restrictions = parse_function_pointer_restrictions_from_file (
448
- restriction_file_opts, message_handler);
445
+ restrictionst commandline_restrictions;
446
+ try
447
+ {
448
+ commandline_restrictions =
449
+ parse_function_pointer_restrictions_from_command_line (restriction_opts);
450
+ typecheck_function_pointer_restrictions (
451
+ goto_model, commandline_restrictions);
452
+ }
453
+ catch (const invalid_restriction_exceptiont &e)
454
+ {
455
+ throw invalid_command_line_argument_exceptiont{
456
+ e.reason , " --" RESTRICT_FUNCTION_POINTER_OPT, e.correct_format };
457
+ }
458
+
459
+ restrictionst file_restrictions;
460
+ try
461
+ {
462
+ auto const restriction_file_opts =
463
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT);
464
+ file_restrictions = parse_function_pointer_restrictions_from_file (
465
+ restriction_file_opts, message_handler);
466
+ typecheck_function_pointer_restrictions (goto_model, file_restrictions);
467
+ }
468
+ catch (const invalid_restriction_exceptiont &e)
469
+ {
470
+ throw deserialization_exceptiont{e.what ()};
471
+ }
449
472
450
- auto const restriction_name_opts =
451
- options.get_list_option (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
452
- auto const name_restrictions = get_function_pointer_by_name_restrictions (
453
- restriction_name_opts, goto_model);
473
+ restrictionst name_restrictions;
474
+ try
475
+ {
476
+ auto const restriction_name_opts =
477
+ options.get_list_option (RESTRICT_FUNCTION_POINTER_BY_NAME_OPT);
478
+ name_restrictions = get_function_pointer_by_name_restrictions (
479
+ restriction_name_opts, goto_model);
480
+ typecheck_function_pointer_restrictions (goto_model, name_restrictions);
481
+ }
482
+ catch (const invalid_restriction_exceptiont &e)
483
+ {
484
+ throw invalid_command_line_argument_exceptiont{
485
+ e.reason , " --" RESTRICT_FUNCTION_POINTER_BY_NAME_OPT, e.correct_format };
486
+ }
454
487
455
488
return {merge_function_pointer_restrictions (
456
489
commandline_restrictions,
@@ -561,8 +594,7 @@ function_pointer_restrictionst::get_function_pointer_by_name_restrictions(
561
594
for (auto const &goto_function : goto_model.goto_functions .function_map )
562
595
{
563
596
for_each_function_call (
564
- goto_function.second ,
565
- [&](const goto_programt::const_targett it) {
597
+ goto_function.second , [&](const goto_programt::const_targett it) {
566
598
const auto restriction = get_by_name_restriction (
567
599
goto_function.second , by_name_restrictions, it);
568
600
0 commit comments