Skip to content

Commit 0c1597e

Browse files
committed
Some cleanup for restrict function pointer by name feature
1 parent 3f098c5 commit 0c1597e

File tree

3 files changed

+116
-98
lines changed

3 files changed

+116
-98
lines changed

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,18 +1038,15 @@ void goto_instrument_parse_optionst::instrument_goto_program()
10381038
parse_function_pointer_restriction_options_from_cmdline(cmdline, options);
10391039

10401040
if(
1041-
!options.get_list_option(RESTRICT_FUNCTION_POINTER_OPT).empty() ||
1042-
!options.get_list_option(RESTRICT_FUNCTION_POINTER_BY_NAME_OPT).empty() ||
1043-
!options.get_list_option(RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT).empty())
1041+
options.is_set(RESTRICT_FUNCTION_POINTER_OPT) ||
1042+
options.is_set(RESTRICT_FUNCTION_POINTER_BY_NAME_OPT) ||
1043+
options.is_set(RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT))
10441044
{
10451045
label_function_pointer_call_sites(goto_model);
10461046

1047-
auto const by_name_restrictions =
1048-
get_function_pointer_by_name_restrictions(goto_model, options);
1049-
10501047
const auto function_pointer_restrictions =
1051-
by_name_restrictions.merge(function_pointer_restrictionst::from_options(
1052-
options, log.get_message_handler()));
1048+
function_pointer_restrictionst::from_options(
1049+
options, goto_model, log.get_message_handler());
10531050

10541051
restrict_function_pointers(goto_model, function_pointer_restrictions);
10551052
}

src/goto-programs/restrict_function_pointers.cpp

Lines changed: 104 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,26 @@ void parse_function_pointer_restriction_options_from_cmdline(
206206
const cmdlinet &cmdline,
207207
optionst &options)
208208
{
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+
}
218229
}
219230

220231
namespace
@@ -240,10 +251,12 @@ merge_function_pointer_restrictions(
240251
}
241252

242253
function_pointer_restrictionst::restrictionst
243-
parse_function_pointer_restrictions_from_command_line(
254+
parse_function_pointer_restrictions(
244255
const std::list<std::string> &restriction_opts,
245256
const std::string &option_name)
246257
{
258+
const std::string option = "--" + option_name;
259+
247260
auto function_pointer_restrictions =
248261
function_pointer_restrictionst::restrictionst{};
249262
for(auto const &restriction_opt : restriction_opts)
@@ -258,21 +271,21 @@ parse_function_pointer_restrictions_from_command_line(
258271
{
259272
throw invalid_command_line_argument_exceptiont{
260273
"couldn't find '/' in `" + restriction_opt + "'",
261-
"--" RESTRICT_FUNCTION_POINTER_OPT,
274+
option,
262275
restriction_format_message};
263276
}
264277
if(pointer_name_end == restriction_opt.size())
265278
{
266279
throw invalid_command_line_argument_exceptiont{
267280
"couldn't find names of targets after '/' in `" + restriction_opt + "'",
268-
"--" RESTRICT_FUNCTION_POINTER_OPT,
281+
option,
269282
restriction_format_message};
270283
}
271284
if(pointer_name_end == 0)
272285
{
273286
throw invalid_command_line_argument_exceptiont{
274287
"couldn't find target name before '/' in `" + restriction_opt + "'",
275-
"--" RESTRICT_FUNCTION_POINTER_OPT};
288+
option_name};
276289
}
277290
auto const pointer_name = restriction_opt.substr(0, pointer_name_end);
278291
auto const target_names_substring =
@@ -282,7 +295,7 @@ parse_function_pointer_restrictions_from_command_line(
282295
{
283296
throw invalid_command_line_argument_exceptiont{
284297
"missing target list for function pointer restriction " + pointer_name,
285-
"--" RESTRICT_FUNCTION_POINTER_OPT,
298+
option,
286299
restriction_format_message};
287300
}
288301

@@ -296,7 +309,7 @@ parse_function_pointer_restrictions_from_command_line(
296309
throw invalid_command_line_argument_exceptiont(
297310
"leading or trailing comma in restrictions for `" + pointer_name +
298311
"'",
299-
"--" RESTRICT_FUNCTION_POINTER_OPT,
312+
option,
300313
restriction_format_message);
301314
}
302315
}
@@ -307,12 +320,20 @@ parse_function_pointer_restrictions_from_command_line(
307320
throw invalid_command_line_argument_exceptiont{
308321
"function pointer restriction for `" + pointer_name +
309322
"' was specified twice",
310-
"--" RESTRICT_FUNCTION_POINTER_OPT};
323+
option};
311324
};
312325
}
313326
return function_pointer_restrictions;
314327
}
315328

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+
316337
function_pointer_restrictionst::restrictionst
317338
parse_function_pointer_restrictions_from_file(
318339
const std::list<std::string> &filenames,
@@ -328,22 +349,84 @@ parse_function_pointer_restrictions_from_file(
328349
}
329350
return merged_restrictions;
330351
}
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+
}
331404
} // namespace
332405

333406
function_pointer_restrictionst function_pointer_restrictionst::from_options(
334407
const optionst &options,
408+
const goto_modelt &goto_model,
335409
message_handlert &message_handler)
336410
{
337411
auto const restriction_opts =
338412
options.get_list_option(RESTRICT_FUNCTION_POINTER_OPT);
339413
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);
342418
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,
344420
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))};
347430
}
348431

349432
function_pointer_restrictionst function_pointer_restrictionst::read_from_file(
@@ -415,60 +498,3 @@ void function_pointer_restrictionst::write_to_file(
415498
}
416499
function_pointer_restrictions_json.output(outFile);
417500
}
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-
}

src/goto-programs/restrict_function_pointers.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,28 @@ void parse_function_pointer_restriction_options_from_cmdline(
5555
optionst &options);
5656

5757
class message_handlert;
58+
5859
struct function_pointer_restrictionst
5960
{
6061
using restrictionst =
6162
std::unordered_map<irep_idt, std::unordered_set<irep_idt>>;
6263
using value_type = restrictionst::value_type;
64+
6365
const restrictionst restrictions;
6466

65-
/// parse function pointer restrictions from command line
66-
///
67-
/// Note: These are are only syntactically checked at this stage,
68-
/// because type checking them requires a goto_modelt
69-
static function_pointer_restrictionst
70-
from_options(const optionst &options, message_handlert &message_handler);
67+
/// Parse function pointer restrictions from command line
68+
static function_pointer_restrictionst from_options(
69+
const optionst &options,
70+
const goto_modelt &goto_model,
71+
message_handlert &message_handler);
7172

7273
static function_pointer_restrictionst read_from_file(
7374
const std::string &filename,
7475
message_handlert &message_handler);
7576

7677
void write_to_file(const std::string &filename) const;
77-
function_pointer_restrictionst
78-
merge(const function_pointer_restrictionst &other) const;
7978
};
8079

81-
function_pointer_restrictionst get_function_pointer_by_name_restrictions(
82-
const goto_modelt &goto_model,
83-
const optionst &options);
84-
8580
/// Apply function pointer restrictions to a goto_model. Each restriction is a
8681
/// mapping from a pointer name to a set of possible targets. Replace calls of
8782
/// these "restricted" pointers with a branch on the value of the function

0 commit comments

Comments
 (0)