@@ -256,10 +256,13 @@ void code_contractst::check_apply_loop_contracts(
256
256
// Forward the loop_head iterator until the start of the body.
257
257
// This is necessary because complex C loop_head conditions could be
258
258
// 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.
259
261
// FIXME: This simple approach wouldn't work when
260
262
// the loop guard in the source file is split across multiple lines.
261
263
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 ())
263
266
loop_head++;
264
267
265
268
// At this point, we are just past the loop head,
@@ -678,6 +681,12 @@ void code_contractst::apply_loop_contract(
678
681
local_may_aliast local_may_alias (goto_function);
679
682
natural_loops_mutablet natural_loops (goto_function.body );
680
683
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
+
681
690
// A graph node type that stores information about a loop.
682
691
// We create a DAG representing nesting of various loops in goto_function,
683
692
// 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)
992
1001
function_obj->second .body , instruction_it, snapshot_instructions);
993
1002
};
994
1003
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.
996
1009
check_frame_conditions (
997
1010
function_obj->first ,
998
1011
function_obj->second .body ,
@@ -1010,8 +1023,6 @@ void code_contractst::check_frame_conditions(
1010
1023
const goto_programt::targett &instruction_end,
1011
1024
assigns_clauset &assigns)
1012
1025
{
1013
- goto_function_inline (goto_functions, function, ns, log .get_message_handler ());
1014
-
1015
1026
for (; instruction_it != instruction_end; ++instruction_it)
1016
1027
{
1017
1028
const auto &pragmas = instruction_it->source_location ().get_pragmas ();
0 commit comments