Skip to content

Commit aa4ed95

Browse files
committed
Refactorings and cleanups for the function pointer restriction feature
1 parent fede34a commit aa4ed95

10 files changed

+291
-219
lines changed

doc/cprover-manual/restrict-function-pointer.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ nothing other than `nullfs`; But perhaps due to the logic being too complicated
142142
symex ends up being unable to figure this out, so in the call to `fs_open()` we
143143
end up branching on all functions matching the signature of
144144
`filesystem_t::open`, which could be quite a few functions within the program.
145-
Worst of all, if it's address is ever taken in the program, as far as the "dumb"
145+
Worst of all, if its address is ever taken in the program, as far as the "dumb"
146146
function pointer removal is concerned it could be `fs_open()` itself due to it
147147
having a matching signature, leading to symex being forced to follow a
148148
potentially infinite recursion until its unwind limit.
@@ -175,6 +175,6 @@ restrictions.
175175

176176
**Note:** as of now, if something goes wrong during type checking (i.e. making
177177
sure that all function pointer replacements refer to functions in the symbol
178-
table that have the correct type), the error message will refer the command line
179-
option `--restrict-function-pointer` regardless of whether the restriction in
180-
question came from the command line or a file.
178+
table that have the correct type), the error message will refer to the command
179+
line option `--restrict-function-pointer` regardless of whether the restriction
180+
in question came from the command line or a file.

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1867,7 +1867,7 @@ void goto_instrument_parse_optionst::help()
18671867
" --no-caching disable caching of intermediate results during transitive function inlining\n" // NOLINT(*)
18681868
" --log <file> log in json format which code segments were inlined, use with --function-inline\n" // NOLINT(*)
18691869
" --remove-function-pointers replace function pointers by case statement over function calls\n" // NOLINT(*)
1870-
RESTRICT_FUNCTION_POINTER_HELP
1870+
HELP_RESTRICT_FUNCTION_POINTER
18711871
HELP_REMOVE_CALLS_NO_BODY
18721872
HELP_REMOVE_CONST_FUNCTION_POINTERS
18731873
" --add-library add models of C library functions\n"

src/goto-programs/goto_program.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,27 +1170,27 @@ struct pointee_address_equalt
11701170
};
11711171

11721172
template <typename GotoFunctionT, typename PredicateT, typename HandlerT>
1173-
void for_each_goto_location_if(
1173+
void for_each_instruction_if(
11741174
GotoFunctionT &&goto_function,
11751175
PredicateT predicate,
1176-
HandlerT handle)
1176+
HandlerT handler)
11771177
{
11781178
auto &&instructions = goto_function.body.instructions;
11791179
for(auto it = instructions.begin(); it != instructions.end(); ++it)
11801180
{
11811181
if(predicate(it))
11821182
{
1183-
handle(it);
1183+
handler(it);
11841184
}
11851185
}
11861186
}
11871187

11881188
template <typename GotoFunctionT, typename HandlerT>
1189-
void for_each_goto_location(GotoFunctionT &&goto_function, HandlerT handle)
1189+
void for_each_instruction(GotoFunctionT &&goto_function, HandlerT handler)
11901190
{
11911191
using iterator_t = decltype(goto_function.body.instructions.begin());
1192-
for_each_goto_location_if(
1193-
goto_function, [](const iterator_t &) { return true; }, handle);
1192+
for_each_instruction_if(
1193+
goto_function, [](const iterator_t &) { return true; }, handler);
11941194
}
11951195

11961196
#define forall_goto_program_instructions(it, program) \

src/goto-programs/label_function_pointer_call_sites.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void label_function_pointer_call_sites(goto_modelt &goto_model)
1515
for(auto &goto_function : goto_model.goto_functions.function_map)
1616
{
1717
std::size_t function_pointer_call_counter = 0;
18-
for_each_goto_location_if(
18+
for_each_instruction_if(
1919
goto_function.second,
2020
[](const goto_programt::targett it) {
2121
return it->is_function_call() && can_cast_expr<dereference_exprt>(
@@ -28,22 +28,30 @@ void label_function_pointer_call_sites(goto_modelt &goto_model)
2828
auto const &source_location = function_call.source_location();
2929
auto const &goto_function_symbol_mode =
3030
goto_model.symbol_table.lookup_ref(goto_function.first).mode;
31-
auto const new_symbol_name =
31+
32+
auto const call_site_symbol_name =
3233
irep_idt{id2string(goto_function.first) + ".function_pointer_call." +
3334
std::to_string(++function_pointer_call_counter)};
35+
36+
// insert new function pointer variable into the symbol table
3437
goto_model.symbol_table.insert([&] {
3538
symbolt function_call_site_symbol{};
3639
function_call_site_symbol.name = function_call_site_symbol.base_name =
37-
function_call_site_symbol.pretty_name = new_symbol_name;
40+
function_call_site_symbol.pretty_name = call_site_symbol_name;
3841
function_call_site_symbol.type =
3942
function_pointer_dereference.pointer().type();
4043
function_call_site_symbol.location = function_call.source_location();
4144
function_call_site_symbol.is_lvalue = true;
4245
function_call_site_symbol.mode = goto_function_symbol_mode;
4346
return function_call_site_symbol;
4447
}());
48+
4549
auto const new_function_pointer =
46-
goto_model.symbol_table.lookup_ref(new_symbol_name).symbol_expr();
50+
goto_model.symbol_table.lookup_ref(call_site_symbol_name)
51+
.symbol_expr();
52+
53+
// add assignment to the new function pointer variable, followed by a
54+
// call of the new variable
4755
auto const assign_instruction = goto_programt::make_assignment(
4856
code_assignt{new_function_pointer,
4957
function_pointer_dereference.pointer()},

src/goto-programs/label_function_pointer_call_sites.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ Author: Diffblue Ltd.
2121
/// only need to be able to handle these two cases.
2222
///
2323
/// It does this by replacing all CALL instructions to function pointers with an
24-
/// assignment to a function pointer variable with a name following the pattern
25-
/// [function_name].function_pointer_call.[N], where "N" is the nth call to a
26-
/// function pointer in the function "function_name".
24+
/// assignment to a new function pointer variable followed by a call to that new
25+
/// function pointer. The name of the introduced variable follows the pattern
26+
/// [function_name].function_pointer_call.[N], where N is the nth call to a
27+
/// function pointer in the function function_name.
2728
void label_function_pointer_call_sites(goto_modelt &goto_model);
2829

2930
#endif // CPROVER_GOTO_PROGRAMS_LABEL_FUNCTION_POINTER_CALL_SITES_H

0 commit comments

Comments
 (0)