@@ -309,8 +309,7 @@ static struct contract_clausest default_loop_contract_clauses(
309309 const dfcc_loop_nesting_grapht &loop_nesting_graph,
310310 const std::size_t loop_id,
311311 const irep_idt &function_id,
312- goto_functiont &goto_function,
313- local_may_aliast &local_may_alias,
312+ const assignst &inferred_assigns,
314313 const bool check_side_effect,
315314 message_handlert &message_handler,
316315 const namespacet &ns)
@@ -361,13 +360,11 @@ static struct contract_clausest default_loop_contract_clauses(
361360 else
362361 {
363362 // infer assigns clause targets if none given
364- auto inferred = dfcc_infer_loop_assigns (
365- local_may_alias, goto_function, loop, message_handler, ns);
366363 log.warning () << " No assigns clause provided for loop " << function_id
367364 << " ." << loop.latch ->loop_number << " at "
368365 << loop.head ->source_location () << " . The inferred set {" ;
369366 bool first = true ;
370- for (const auto &expr : inferred )
367+ for (const auto &expr : inferred_assigns )
371368 {
372369 if (!first)
373370 {
@@ -379,7 +376,7 @@ static struct contract_clausest default_loop_contract_clauses(
379376 log.warning () << " } might be incomplete or imprecise, please provide an "
380377 " assigns clause if the analysis fails."
381378 << messaget::eom;
382- result.assigns . swap (inferred) ;
379+ result.assigns = inferred_assigns ;
383380 }
384381
385382 if (result.decreases_clauses .empty ())
@@ -400,7 +397,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
400397 goto_functiont &goto_function,
401398 const std::map<std::size_t , dfcc_loop_infot> &loop_info_map,
402399 dirtyt &dirty,
403- local_may_aliast &local_may_alias ,
400+ const assignst &inferred_assigns ,
404401 const bool check_side_effect,
405402 message_handlert &message_handler,
406403 dfcc_libraryt &library,
@@ -436,8 +433,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
436433 loop_nesting_graph,
437434 loop_id,
438435 function_id,
439- goto_function,
440- local_may_alias,
436+ inferred_assigns,
441437 check_side_effect,
442438 message_handler,
443439 ns);
@@ -488,6 +484,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
488484}
489485
490486dfcc_cfg_infot::dfcc_cfg_infot (
487+ goto_modelt &goto_model,
491488 const irep_idt &function_id,
492489 goto_functiont &goto_function,
493490 const exprt &top_level_write_set,
@@ -506,6 +503,9 @@ dfcc_cfg_infot::dfcc_cfg_infot(
506503 // Clean up possible fake loops that are due to do { ... } while(0);
507504 simplify_gotos (goto_program, ns);
508505
506+ // From loop number to the inferred loop assigns.
507+ std::map<std::size_t , assignst> inferred_loop_assigns_map;
508+
509509 if (loop_contract_config.apply_loop_contracts )
510510 {
511511 messaget log (message_handler);
@@ -526,9 +526,23 @@ dfcc_cfg_infot::dfcc_cfg_infot(
526526
527527 auto topsorted = loop_nesting_graph.topsort ();
528528
529+ bool has_loops_with_contracts = false ;
529530 for (const auto idx : topsorted)
530531 {
531532 topsorted_loops.push_back (idx);
533+ has_loops_with_contracts |= has_contract (
534+ loop_nesting_graph[idx].latch , loop_contract_config.check_side_effect );
535+ }
536+
537+ // We infer loop assigns for all loops in the function.
538+ if (has_loops_with_contracts)
539+ {
540+ dfcc_infer_loop_assigns_for_function (
541+ inferred_loop_assigns_map,
542+ goto_model.goto_functions ,
543+ goto_function,
544+ message_handler,
545+ ns);
532546 }
533547 }
534548
@@ -548,10 +562,11 @@ dfcc_cfg_infot::dfcc_cfg_infot(
548562
549563 // generate dfcc_cfg_loop_info for loops and add to loop_info_map
550564 dirtyt dirty (goto_function);
551- local_may_aliast local_may_alias (goto_function);
552565
553566 for (const auto &loop_id : topsorted_loops)
554567 {
568+ auto inferred_loop_assigns =
569+ inferred_loop_assigns_map[loop_nesting_graph[loop_id].latch ->loop_number ];
555570 loop_info_map.insert (
556571 {loop_id,
557572 gen_dfcc_loop_info (
@@ -561,7 +576,7 @@ dfcc_cfg_infot::dfcc_cfg_infot(
561576 goto_function,
562577 loop_info_map,
563578 dirty,
564- local_may_alias ,
579+ inferred_loop_assigns ,
565580 loop_contract_config.check_side_effect ,
566581 message_handler,
567582 library,
0 commit comments