Skip to content

Commit 911db55

Browse files
committed
refactor function call inling for code contracts
Function call inlining was earlier performed on the same function multiple times if it had multiple loops. We refactor the inlining call out and only inline the function once, even if it has multiple loops.
1 parent 26760d3 commit 911db55

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

src/goto-instrument/contracts/contracts.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,13 @@ void code_contractst::check_apply_loop_contracts(
256256
// Forward the loop_head iterator until the start of the body.
257257
// This is necessary because complex C loop_head conditions could be
258258
// converted to multiple GOTO instructions (e.g. temporaries are introduced).
259+
// If the loop_head location shifts to a different function,
260+
// assume that it's an inlined function and keep skipping.
259261
// FIXME: This simple approach wouldn't work when
260262
// the loop guard in the source file is split across multiple lines.
261263
const auto head_loc = loop_head->source_location();
262-
while(loop_head->source_location() == head_loc)
264+
while(loop_head->source_location() == head_loc ||
265+
loop_head->source_location().get_function() != head_loc.get_function())
263266
loop_head++;
264267

265268
// At this point, we are just past the loop head,
@@ -678,6 +681,12 @@ void code_contractst::apply_loop_contract(
678681
local_may_aliast local_may_alias(goto_function);
679682
natural_loops_mutablet natural_loops(goto_function.body);
680683

684+
if(!natural_loops.loop_map.size())
685+
return;
686+
687+
goto_function_inline(
688+
goto_functions, function_name, ns, log.get_message_handler());
689+
681690
// A graph node type that stores information about a loop.
682691
// We create a DAG representing nesting of various loops in goto_function,
683692
// sort them topologically, and instrument them in the top-sorted order.
@@ -992,7 +1001,11 @@ bool code_contractst::check_frame_conditions_function(const irep_idt &function)
9921001
function_obj->second.body, instruction_it, snapshot_instructions);
9931002
};
9941003

995-
// Insert aliasing assertions
1004+
// Inline all function calls.
1005+
goto_function_inline(
1006+
goto_functions, function_obj->first, ns, log.get_message_handler());
1007+
1008+
// Insert write set inclusion checks.
9961009
check_frame_conditions(
9971010
function_obj->first,
9981011
function_obj->second.body,
@@ -1010,8 +1023,6 @@ void code_contractst::check_frame_conditions(
10101023
const goto_programt::targett &instruction_end,
10111024
assigns_clauset &assigns)
10121025
{
1013-
goto_function_inline(goto_functions, function, ns, log.get_message_handler());
1014-
10151026
for(; instruction_it != instruction_end; ++instruction_it)
10161027
{
10171028
const auto &pragmas = instruction_it->source_location().get_pragmas();

0 commit comments

Comments
 (0)