@@ -44,7 +44,8 @@ bool dep_graph_domaint::merge(
44
44
45
45
changed|=merge_control_dependencies (
46
46
src.control_deps ,
47
- src.control_dep_candidates );
47
+ src.control_dep_candidates ,
48
+ src.control_dep_calls );
48
49
49
50
has_changed=false ;
50
51
has_values=tvt::unknown ();
@@ -74,7 +75,9 @@ void dep_graph_domaint::control_dependencies(
74
75
control_dep_candidates.insert (from);
75
76
else if (from->is_end_function ())
76
77
{
78
+ control_deps.clear ();
77
79
control_dep_candidates.clear ();
80
+ control_dep_calls.clear ();
78
81
return ;
79
82
}
80
83
@@ -149,6 +152,7 @@ void dep_graph_domaint::control_dependencies(
149
152
}
150
153
151
154
control_deps.insert (std::make_pair (cd, branch));
155
+ control_dep_calls.clear ();
152
156
}
153
157
}
154
158
@@ -259,7 +263,8 @@ void dep_graph_domaint::control_dependencies(
259
263
260
264
bool dep_graph_domaint::merge_control_dependencies (
261
265
const control_depst &other_control_deps,
262
- const control_dep_candidatest &other_control_dep_candidates)
266
+ const control_dep_candidatest &other_control_dep_candidates,
267
+ const control_dep_callst &other_control_dep_calls)
263
268
{
264
269
bool changed=false ;
265
270
@@ -308,6 +313,16 @@ bool dep_graph_domaint::merge_control_dependencies(
308
313
309
314
changed|=n!=control_dep_candidates.size ();
310
315
316
+ // Merge call control dependencies
317
+
318
+ n=control_dep_calls.size ();
319
+
320
+ control_dep_calls.insert (
321
+ other_control_dep_calls.begin (),
322
+ other_control_dep_calls.end ());
323
+
324
+ changed|=n!=control_dep_calls.size ();
325
+
311
326
return changed;
312
327
}
313
328
@@ -448,25 +463,6 @@ void dep_graph_domaint::transform(
448
463
dependence_grapht *dep_graph=dynamic_cast <dependence_grapht*>(&ai);
449
464
assert (dep_graph!=nullptr );
450
465
451
- // We do not propagate control dependencies on function calls, i.e., only the
452
- // entry point of a function should have a control dependency on the call
453
- if (!control_deps.empty ())
454
- {
455
- const goto_programt::const_targett &dep = control_deps.begin ()->first ;
456
- if (dep->is_function_call ())
457
- {
458
- INVARIANT (
459
- std::all_of (
460
- std::next (control_deps.begin ()),
461
- control_deps.end (),
462
- [](const std::pair<const goto_programt::const_targett, tvt> &d)
463
- { return d.first ->is_function_call (); }),
464
- " All entries must be function calls" );
465
-
466
- control_deps.clear ();
467
- }
468
- }
469
-
470
466
// propagate control dependencies across function calls
471
467
if (from->is_function_call ())
472
468
{
@@ -492,13 +488,15 @@ void dep_graph_domaint::transform(
492
488
// modify abstract state of return location
493
489
if (s->merge_control_dependencies (
494
490
control_deps,
495
- control_dep_candidates))
491
+ control_dep_candidates,
492
+ control_dep_calls))
496
493
s->has_changed =true ;
497
494
498
495
control_deps.clear ();
499
- control_deps.insert (std::make_pair (from, tvt::unknown ()));
500
-
501
496
control_dep_candidates.clear ();
497
+
498
+ control_dep_calls.clear ();
499
+ control_dep_calls.insert (from);
502
500
}
503
501
}
504
502
else
@@ -512,7 +510,7 @@ void dep_graph_domaint::output(
512
510
const ai_baset &ai,
513
511
const namespacet &ns) const
514
512
{
515
- if (!control_deps.empty ())
513
+ if (!control_deps.empty () || !control_dep_calls. empty () )
516
514
{
517
515
out << " Control dependencies: " ;
518
516
for (control_depst::const_iterator
@@ -528,6 +526,18 @@ void dep_graph_domaint::output(
528
526
529
527
out << cd->location_number << " [" << branch << " ]" ;
530
528
}
529
+
530
+ for (control_dep_callst::const_iterator
531
+ it=control_dep_calls.begin ();
532
+ it!=control_dep_calls.end ();
533
+ ++it)
534
+ {
535
+ if (!control_deps.empty () || it!=control_dep_calls.begin ())
536
+ out << " ," ;
537
+
538
+ out << (*it)->location_number << " [CALL]" ;
539
+ }
540
+
531
541
out << " \n " ;
532
542
}
533
543
@@ -584,6 +594,17 @@ jsont dep_graph_domaint::output_json(
584
594
link[" branch" ]=json_stringt (branch.to_string ());
585
595
}
586
596
597
+ for (const auto &target : control_dep_calls)
598
+ {
599
+ json_objectt &link=graph.push_back ().make_object ();
600
+
601
+ link[" locationNumber" ]=
602
+ json_numbert (std::to_string (target->location_number ));
603
+ link[" sourceLocation" ]=json (target->source_location );
604
+ link[" type" ]=json_stringt (" control" );
605
+ link[" branch" ]=json_stringt (" CALL" );
606
+ }
607
+
587
608
for (const auto &dd : data_deps)
588
609
{
589
610
goto_programt::const_targett target=dd.first ;
@@ -628,6 +649,17 @@ jsont dep_graph_domaint::output_json_additional(
628
649
link[" branch" ]=json_stringt (branch.to_string ());
629
650
}
630
651
652
+ for (const auto &target : control_dep_calls)
653
+ {
654
+ json_objectt &link=graph.push_back ().make_object ();
655
+
656
+ link[" locationNumber" ]=
657
+ json_numbert (std::to_string (target->location_number ));
658
+ link[" sourceLocation" ]=json (target->source_location );
659
+ link[" type" ]=json_stringt (" control" );
660
+ link[" branch" ]=json_stringt (" CALL" );
661
+ }
662
+
631
663
for (const auto &dd : base_state.data_deps )
632
664
{
633
665
goto_programt::const_targett target=dd.first ;
@@ -704,6 +736,9 @@ void dep_graph_domaint::populate_dep_graph(
704
736
for (const auto &c_dep : control_deps)
705
737
dep_graph.add_dep (dep_edget::kindt::CTRL, c_dep.first , this_loc);
706
738
739
+ for (const auto &c_dep : control_dep_calls)
740
+ dep_graph.add_dep (dep_edget::kindt::CTRL, c_dep, this_loc);
741
+
707
742
for (const auto &d_dep : data_deps)
708
743
dep_graph.add_dep (dep_edget::kindt::DATA, d_dep.first , this_loc);
709
744
}
0 commit comments