@@ -309,8 +309,7 @@ static struct contract_clausest default_loop_contract_clauses(
309
309
const dfcc_loop_nesting_grapht &loop_nesting_graph,
310
310
const std::size_t loop_id,
311
311
const irep_idt &function_id,
312
- goto_functiont &goto_function,
313
- local_may_aliast &local_may_alias,
312
+ const assignst &inferred_assigns,
314
313
const bool check_side_effect,
315
314
message_handlert &message_handler,
316
315
const namespacet &ns)
@@ -361,13 +360,11 @@ static struct contract_clausest default_loop_contract_clauses(
361
360
else
362
361
{
363
362
// infer assigns clause targets if none given
364
- auto inferred = dfcc_infer_loop_assigns (
365
- local_may_alias, goto_function, loop, message_handler, ns);
366
363
log .warning () << " No assigns clause provided for loop " << function_id
367
364
<< " ." << loop.latch ->loop_number << " at "
368
365
<< loop.head ->source_location () << " . The inferred set {" ;
369
366
bool first = true ;
370
- for (const auto &expr : inferred )
367
+ for (const auto &expr : inferred_assigns )
371
368
{
372
369
if (!first)
373
370
{
@@ -379,7 +376,7 @@ static struct contract_clausest default_loop_contract_clauses(
379
376
log .warning () << " } might be incomplete or imprecise, please provide an "
380
377
" assigns clause if the analysis fails."
381
378
<< messaget::eom;
382
- result.assigns . swap (inferred) ;
379
+ result.assigns = inferred_assigns ;
383
380
}
384
381
385
382
if (result.decreases_clauses .empty ())
@@ -400,7 +397,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
400
397
goto_functiont &goto_function,
401
398
const std::map<std::size_t , dfcc_loop_infot> &loop_info_map,
402
399
dirtyt &dirty,
403
- local_may_aliast &local_may_alias ,
400
+ const assignst &inferred_assigns ,
404
401
const bool check_side_effect,
405
402
message_handlert &message_handler,
406
403
dfcc_libraryt &library,
@@ -436,8 +433,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
436
433
loop_nesting_graph,
437
434
loop_id,
438
435
function_id,
439
- goto_function,
440
- local_may_alias,
436
+ inferred_assigns,
441
437
check_side_effect,
442
438
message_handler,
443
439
ns);
@@ -488,6 +484,7 @@ static dfcc_loop_infot gen_dfcc_loop_info(
488
484
}
489
485
490
486
dfcc_cfg_infot::dfcc_cfg_infot (
487
+ goto_modelt &goto_model,
491
488
const irep_idt &function_id,
492
489
goto_functiont &goto_function,
493
490
const exprt &top_level_write_set,
@@ -506,6 +503,9 @@ dfcc_cfg_infot::dfcc_cfg_infot(
506
503
// Clean up possible fake loops that are due to do { ... } while(0);
507
504
simplify_gotos (goto_program, ns);
508
505
506
+ // From loop number to the inferred loop assigns.
507
+ std::map<std::size_t , assignst> inferred_loop_assigns_map;
508
+
509
509
if (loop_contract_config.apply_loop_contracts )
510
510
{
511
511
messaget log (message_handler);
@@ -526,9 +526,23 @@ dfcc_cfg_infot::dfcc_cfg_infot(
526
526
527
527
auto topsorted = loop_nesting_graph.topsort ();
528
528
529
+ bool has_loops_with_contracts = false ;
529
530
for (const auto idx : topsorted)
530
531
{
531
532
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);
532
546
}
533
547
}
534
548
@@ -548,10 +562,11 @@ dfcc_cfg_infot::dfcc_cfg_infot(
548
562
549
563
// generate dfcc_cfg_loop_info for loops and add to loop_info_map
550
564
dirtyt dirty (goto_function);
551
- local_may_aliast local_may_alias (goto_function);
552
565
553
566
for (const auto &loop_id : topsorted_loops)
554
567
{
568
+ auto inferred_loop_assigns =
569
+ inferred_loop_assigns_map[loop_nesting_graph[loop_id].latch ->loop_number ];
555
570
loop_info_map.insert (
556
571
{loop_id,
557
572
gen_dfcc_loop_info (
@@ -561,7 +576,7 @@ dfcc_cfg_infot::dfcc_cfg_infot(
561
576
goto_function,
562
577
loop_info_map,
563
578
dirty,
564
- local_may_alias ,
579
+ inferred_loop_assigns ,
565
580
loop_contract_config.check_side_effect ,
566
581
message_handler,
567
582
library,
0 commit comments