@@ -274,7 +274,7 @@ ssa_exprt goto_symex_statet::rename_ssa(ssa_exprt ssa, const namespacet &ns)
274
274
return ssa;
275
275
}
276
276
277
- // / Ensure `rename_ssa` gets compiled for L0
277
+ // explicitly instantiate templates
278
278
template ssa_exprt
279
279
goto_symex_statet::rename_ssa<L0>(ssa_exprt ssa, const namespacet &ns);
280
280
template ssa_exprt
@@ -301,8 +301,13 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
301
301
else if (level==L2)
302
302
{
303
303
ssa = set_indices<L1>(std::move (ssa), ns).get ();
304
- rename <level>(expr.type (), ssa.get_identifier (), ns);
305
- ssa.update_type ();
304
+ if (
305
+ auto renamed_type =
306
+ rename_type<level>(expr.type (), ssa.get_identifier (), ns))
307
+ {
308
+ ssa.type () = std::move (*renamed_type);
309
+ ssa.update_type ();
310
+ }
306
311
307
312
if (l2_thread_read_encoding (ssa, ns))
308
313
{
@@ -327,11 +332,18 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
327
332
}
328
333
else if (expr.id ()==ID_symbol)
329
334
{
330
- const auto &type = as_const (expr).type ();
331
-
332
335
// we never rename function symbols
333
- if (type.id () == ID_code || type.id () == ID_mathematical_function)
334
- rename <level>(expr.type (), to_symbol_expr (expr).get_identifier (), ns);
336
+ if (
337
+ expr.type ().id () == ID_code ||
338
+ expr.type ().id () == ID_mathematical_function)
339
+ {
340
+ if (
341
+ auto renamed_type = rename_type<level>(
342
+ expr.type (), to_symbol_expr (expr).get_identifier (), ns))
343
+ {
344
+ expr.type () = std::move (*renamed_type);
345
+ }
346
+ }
335
347
else
336
348
expr = rename <level>(ssa_exprt{expr}, ns);
337
349
}
@@ -344,7 +356,10 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
344
356
}
345
357
else
346
358
{
347
- rename <level>(expr.type (), irep_idt (), ns);
359
+ if (auto renamed_type = rename_type<level>(expr.type (), irep_idt (), ns))
360
+ {
361
+ expr.type () = std::move (*renamed_type);
362
+ }
348
363
349
364
// do this recursively
350
365
Forall_operands (it, expr)
@@ -363,8 +378,6 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
363
378
return expr;
364
379
}
365
380
366
- template exprt goto_symex_statet::rename<L1>(exprt expr, const namespacet &ns);
367
-
368
381
// / thread encoding
369
382
bool goto_symex_statet::l2_thread_read_encoding (
370
383
ssa_exprt &expr,
@@ -548,8 +561,13 @@ void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
548
561
// only do L1!
549
562
ssa = set_indices<L1>(std::move (ssa), ns).get ();
550
563
551
- rename <level>(expr.type (), ssa.get_identifier (), ns);
552
- ssa.update_type ();
564
+ if (
565
+ auto renamed_type =
566
+ rename_type<level>(expr.type (), ssa.get_identifier (), ns))
567
+ {
568
+ ssa.type () = std::move (*renamed_type);
569
+ ssa.update_type ();
570
+ }
553
571
}
554
572
else if (expr.id ()==ID_symbol)
555
573
{
@@ -667,11 +685,29 @@ void goto_symex_statet::rename(
667
685
typet &type,
668
686
const irep_idt &l1_identifier,
669
687
const namespacet &ns)
688
+ {
689
+ if (auto renamed = rename_type<level>(type, l1_identifier, ns))
690
+ type = std::move (*renamed);
691
+ }
692
+
693
+ // explicitly instantiate templates
694
+ // / \cond
695
+ template void goto_symex_statet::rename<L2>(
696
+ typet &type,
697
+ const irep_idt &l1_identifier,
698
+ const namespacet &ns);
699
+ // / \endcond
700
+
701
+ template <levelt level>
702
+ optionalt<typet> goto_symex_statet::rename_type (
703
+ const typet &type,
704
+ const irep_idt &l1_identifier,
705
+ const namespacet &ns)
670
706
{
671
707
// check whether there are symbol expressions in the type; if not, there
672
708
// is no need to expand the struct/union tags in the type
673
709
if (!requires_renaming (type, ns))
674
- return ; // no action
710
+ return {};
675
711
676
712
// rename all the symbols with their last known value
677
713
// to the given level
@@ -693,46 +729,92 @@ void goto_symex_statet::rename(
693
729
to_array_type (type).is_incomplete () ||
694
730
to_array_type (type_prev).is_complete ())
695
731
{
696
- type=l1_type_entry.first ->second ;
697
- return ;
732
+ return l1_type_entry.first ->second ;
698
733
}
699
734
}
700
735
}
701
736
702
- // expand struct and union tag types
703
- type = ns.follow (type);
737
+ optionalt<typet> result;
704
738
705
739
if (type.id ()==ID_array)
706
740
{
707
741
auto &array_type = to_array_type (type);
708
- rename <level>(array_type.subtype (), irep_idt (), ns);
709
- array_type.size () = rename <level>(std::move (array_type.size ()), ns);
742
+ auto renamed_subtype =
743
+ rename_type<level>(array_type.subtype (), irep_idt (), ns);
744
+ auto renamed_size = rename <level>(array_type.size (), ns);
745
+
746
+ if (renamed_subtype.has_value () || renamed_size != array_type.size ())
747
+ {
748
+ array_typet result_type = array_type;
749
+
750
+ if (renamed_subtype.has_value ())
751
+ result_type.subtype () = std::move (*renamed_subtype);
752
+
753
+ if (renamed_size != array_type.size ())
754
+ result_type.size () = std::move (renamed_size);
755
+
756
+ result = std::move (result_type);
757
+ }
710
758
}
711
759
else if (type.id () == ID_struct || type.id () == ID_union)
712
760
{
713
- struct_union_typet & s_u_type= to_struct_union_type (type);
714
- struct_union_typet::componentst &components=s_u_type. components () ;
761
+ struct_union_typet s_u_type = to_struct_union_type (type);
762
+ bool modified = false ;
715
763
716
- for (auto &component : components)
764
+ struct_union_typet::componentst::iterator comp_it =
765
+ s_u_type.components ().begin ();
766
+ for (auto &component : to_struct_union_type (type).components ())
717
767
{
718
768
// be careful, or it might get cyclic
719
769
if (component.type ().id () == ID_array)
720
770
{
721
771
auto &array_type = to_array_type (component.type ());
722
- array_type.size () = rename <level>(std::move (array_type.size ()), ns);
772
+ auto renamed_expr = rename <level>(array_type.size (), ns);
773
+ if (renamed_expr != array_type.size ())
774
+ {
775
+ to_array_type (comp_it->type ()).size () = std::move (renamed_expr);
776
+ modified = true ;
777
+ }
723
778
}
724
779
else if (component.type ().id () != ID_pointer)
725
- rename <level>(component.type (), irep_idt (), ns);
780
+ {
781
+ if (
782
+ auto renamed_type =
783
+ rename_type<level>(component.type (), irep_idt (), ns))
784
+ {
785
+ comp_it->type () = std::move (*renamed_type);
786
+ modified = true ;
787
+ }
788
+ }
789
+
790
+ ++comp_it;
726
791
}
792
+
793
+ if (modified)
794
+ result = std::move (s_u_type);
727
795
}
728
796
else if (type.id ()==ID_pointer)
729
797
{
730
- rename <level>(to_pointer_type (type).subtype (), irep_idt (), ns);
798
+ auto renamed_subtype =
799
+ rename_type<level>(to_pointer_type (type).subtype (), irep_idt (), ns);
800
+ if (renamed_subtype.has_value ())
801
+ {
802
+ result = pointer_typet{std::move (*renamed_subtype),
803
+ to_pointer_type (type).get_width ()};
804
+ }
805
+ }
806
+ else if (type.id () == ID_struct_tag || type.id () == ID_union_tag)
807
+ {
808
+ const typet &followed_type = ns.follow (type);
809
+ result = rename_type<level>(followed_type, l1_identifier, ns);
810
+ if (!result.has_value ())
811
+ result = followed_type;
731
812
}
732
813
733
- if (level==L2 &&
734
- !l1_identifier.empty ())
735
- l1_type_entry.first ->second =type;
814
+ if (level == L2 && !l1_identifier.empty () && result.has_value ())
815
+ l1_type_entry.first ->second = *result;
816
+
817
+ return result;
736
818
}
737
819
738
820
static void get_l1_name (exprt &expr)
0 commit comments