@@ -281,10 +281,13 @@ ssa_exprt goto_symex_statet::rename_ssa(ssa_exprt ssa, const namespacet &ns)
281
281
return ssa;
282
282
}
283
283
284
- // / Ensure `rename_ssa` gets compiled for L0
284
+ // explicitly instantiate templates
285
285
template ssa_exprt goto_symex_statet::rename_ssa<goto_symex_statet::L0>(
286
286
ssa_exprt ssa,
287
287
const namespacet &ns);
288
+ template ssa_exprt goto_symex_statet::rename_ssa<goto_symex_statet::L1>(
289
+ ssa_exprt ssa,
290
+ const namespacet &ns);
288
291
289
292
template <goto_symex_statet::levelt level>
290
293
exprt goto_symex_statet::rename (exprt expr, const namespacet &ns)
@@ -298,17 +301,15 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
298
301
299
302
if (level == L0)
300
303
{
301
- ssa = rename_ssa<L0>( std::move ( ssa) , ns);
304
+ set_l0_indices ( ssa, ns);
302
305
}
303
306
else if (level == L1)
304
307
{
305
- ssa = rename_ssa<L1>( std::move ( ssa) , ns);
308
+ set_l1_indices ( ssa, ns);
306
309
}
307
310
else if (level==L2)
308
311
{
309
312
set_l1_indices (ssa, ns);
310
- rename <level>(expr.type (), ssa.get_identifier (), ns);
311
- ssa.update_type ();
312
313
313
314
if (l2_thread_read_encoding (ssa, ns))
314
315
{
@@ -327,15 +328,40 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
327
328
if (p_it != propagation.end ())
328
329
expr=p_it->second ; // already L2
329
330
else
331
+ {
332
+ if (
333
+ auto renamed_type =
334
+ rename_type<level>(expr.type (), ssa.get_identifier (), ns))
335
+ {
336
+ ssa.type () = std::move (*renamed_type);
337
+ ssa.update_type ();
338
+ }
339
+
330
340
set_l2_indices (ssa, ns);
341
+ }
331
342
}
332
343
}
344
+
345
+ if (
346
+ auto renamed_type =
347
+ rename_type<level>(expr.type (), ssa.get_identifier (), ns))
348
+ {
349
+ ssa.type () = std::move (*renamed_type);
350
+ ssa.update_type ();
351
+ }
333
352
}
334
353
else if (expr.id ()==ID_symbol)
335
354
{
336
355
// we never rename function symbols
337
- if (as_const (expr).type ().id () == ID_code)
338
- rename <level>(expr.type (), to_symbol_expr (expr).get_identifier (), ns);
356
+ if (expr.type ().id () == ID_code)
357
+ {
358
+ if (
359
+ auto renamed_type = rename_type<level>(
360
+ expr.type (), to_symbol_expr (expr).get_identifier (), ns))
361
+ {
362
+ expr.type () = std::move (*renamed_type);
363
+ }
364
+ }
339
365
else
340
366
expr = rename <level>(ssa_exprt{expr}, ns);
341
367
}
@@ -348,7 +374,10 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
348
374
}
349
375
else
350
376
{
351
- rename <level>(expr.type (), irep_idt (), ns);
377
+ if (auto renamed_type = rename_type<level>(expr.type (), irep_idt (), ns))
378
+ {
379
+ expr.type () = std::move (*renamed_type);
380
+ }
352
381
353
382
// do this recursively
354
383
Forall_operands (it, expr)
@@ -555,8 +584,13 @@ void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
555
584
// only do L1!
556
585
set_l1_indices (ssa, ns);
557
586
558
- rename <level>(expr.type (), ssa.get_identifier (), ns);
559
- ssa.update_type ();
587
+ if (
588
+ auto renamed_type =
589
+ rename_type<level>(expr.type (), ssa.get_identifier (), ns))
590
+ {
591
+ ssa.type () = std::move (*renamed_type);
592
+ ssa.update_type ();
593
+ }
560
594
}
561
595
else if (expr.id ()==ID_symbol)
562
596
{
@@ -680,11 +714,27 @@ void goto_symex_statet::rename(
680
714
typet &type,
681
715
const irep_idt &l1_identifier,
682
716
const namespacet &ns)
717
+ {
718
+ if (auto renamed = rename_type<level>(type, l1_identifier, ns))
719
+ type = std::move (*renamed);
720
+ }
721
+
722
+ // explicitly instantiate templates
723
+ template void goto_symex_statet::rename<goto_symex_statet::L2>(
724
+ typet &type,
725
+ const irep_idt &l1_identifier,
726
+ const namespacet &ns);
727
+
728
+ template <goto_symex_statet::levelt level>
729
+ optionalt<typet> goto_symex_statet::rename_type (
730
+ const typet &type,
731
+ const irep_idt &l1_identifier,
732
+ const namespacet &ns)
683
733
{
684
734
// check whether there are symbol expressions in the type; if not, there
685
735
// is no need to expand the struct/union tags in the type
686
736
if (!requires_renaming (type, ns))
687
- return ; // no action
737
+ return {};
688
738
689
739
// rename all the symbols with their last known value
690
740
// to the given level
@@ -706,46 +756,100 @@ void goto_symex_statet::rename(
706
756
to_array_type (type).is_incomplete () ||
707
757
to_array_type (type_prev).is_complete ())
708
758
{
709
- type=l1_type_entry.first ->second ;
710
- return ;
759
+ return l1_type_entry.first ->second ;
711
760
}
712
761
}
713
762
}
714
763
715
- // expand struct and union tag types
716
- type = ns.follow (type);
764
+ optionalt<typet> result;
717
765
718
766
if (type.id ()==ID_array)
719
767
{
720
768
auto &array_type = to_array_type (type);
721
- rename <level>(array_type.subtype (), irep_idt (), ns);
722
- array_type.size () = rename <level>(std::move (array_type.size ()), ns);
769
+ auto renamed_subtype =
770
+ rename_type<level>(array_type.subtype (), irep_idt (), ns);
771
+ auto renamed_size = rename <level>(array_type.size (), ns);
772
+
773
+ if (renamed_subtype.has_value () || renamed_size != array_type.size ())
774
+ {
775
+ array_typet result_type = array_type;
776
+
777
+ if (renamed_subtype.has_value ())
778
+ result_type.subtype () = std::move (*renamed_subtype);
779
+
780
+ if (renamed_size != array_type.size ())
781
+ result_type.size () = std::move (renamed_size);
782
+
783
+ result = std::move (result_type);
784
+ }
723
785
}
724
786
else if (type.id () == ID_struct || type.id () == ID_union)
725
787
{
726
- struct_union_typet & s_u_type= to_struct_union_type (type);
727
- struct_union_typet::componentst &components=s_u_type. components () ;
788
+ struct_union_typet s_u_type = to_struct_union_type (type);
789
+ bool modified = false ;
728
790
729
- for (auto &component : components)
791
+ struct_union_typet::componentst::iterator comp_it =
792
+ s_u_type.components ().begin ();
793
+ for (auto &component : to_struct_union_type (type).components ())
730
794
{
731
795
// be careful, or it might get cyclic
732
796
if (component.type ().id () == ID_array)
733
797
{
734
798
auto &array_type = to_array_type (component.type ());
735
- array_type.size () = rename <level>(std::move (array_type.size ()), ns);
799
+ auto renamed_expr = rename <level>(array_type.size (), ns);
800
+ if (renamed_expr != array_type.size ())
801
+ {
802
+ to_array_type (comp_it->type ()).size () = std::move (renamed_expr);
803
+ modified = true ;
804
+ }
736
805
}
737
806
else if (component.type ().id () != ID_pointer)
738
- rename <level>(component.type (), irep_idt (), ns);
807
+ {
808
+ if (
809
+ auto renamed_type =
810
+ rename_type<level>(component.type (), irep_idt (), ns))
811
+ {
812
+ comp_it->type () = std::move (*renamed_type);
813
+ modified = true ;
814
+ }
815
+ }
816
+
817
+ ++comp_it;
739
818
}
819
+
820
+ if (modified)
821
+ result = std::move (s_u_type);
740
822
}
741
823
else if (type.id ()==ID_pointer)
742
824
{
743
- rename <level>(to_pointer_type (type).subtype (), irep_idt (), ns);
825
+ if (
826
+ auto renamed_subtype =
827
+ rename_type<level>(to_pointer_type (type).subtype (), irep_idt (), ns))
828
+ {
829
+ pointer_typet pointer_type = to_pointer_type (type);
830
+ pointer_type.subtype () = std::move (*renamed_subtype);
831
+ result = std::move (pointer_type);
832
+ }
833
+ }
834
+ else if (type.id () == ID_symbol_type)
835
+ {
836
+ const symbolt &symbol = ns.lookup (to_symbol_type (type));
837
+ result = rename_type<level>(symbol.type , l1_identifier, ns);
838
+ if (!result.has_value ())
839
+ result = symbol.type ;
840
+ }
841
+ else if (type.id () == ID_struct_tag || type.id () == ID_union_tag)
842
+ {
843
+ const symbolt &symbol = ns.lookup (to_tag_type (type));
844
+ result = rename_type<level>(symbol.type , l1_identifier, ns);
845
+ if (!result.has_value ())
846
+ result = symbol.type ;
744
847
}
745
848
746
- if (level==L2 &&
747
- !l1_identifier.empty ())
748
- l1_type_entry.first ->second =type;
849
+ if (level == L2 && !l1_identifier.empty () && result.has_value ())
850
+ l1_type_entry.first ->second = *result;
851
+
852
+ return result;
749
853
}
750
854
751
855
static void get_l1_name (exprt &expr)
0 commit comments