@@ -368,9 +368,15 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
368
368
else if (expr.id ()==ID_address_of)
369
369
{
370
370
auto &address_of_expr = to_address_of_expr (expr);
371
- rename_address<level>(address_of_expr.object (), ns);
372
- to_pointer_type (expr.type ()).subtype () =
373
- as_const (address_of_expr).object ().type ();
371
+ auto renamed_object = rename_address<level>(address_of_expr.object (), ns);
372
+
373
+ if (renamed_object.has_value ())
374
+ {
375
+ address_of_exprt result = address_of_expr;
376
+ result.object () = std::move (*renamed_object);
377
+ to_pointer_type (result.type ()).subtype () = result.object ().type ();
378
+ expr = std::move (result);
379
+ }
374
380
}
375
381
else
376
382
{
@@ -574,12 +580,13 @@ bool goto_symex_statet::l2_thread_write_encoding(
574
580
}
575
581
576
582
template <goto_symex_statet::levelt level>
577
- void goto_symex_statet::rename_address (exprt &expr, const namespacet &ns)
583
+ optionalt<exprt>
584
+ goto_symex_statet::rename_address (const exprt &expr, const namespacet &ns)
578
585
{
579
586
if (expr.id ()==ID_symbol &&
580
587
expr.get_bool (ID_C_SSA_symbol))
581
588
{
582
- ssa_exprt & ssa= to_ssa_expr (expr);
589
+ ssa_exprt ssa = to_ssa_expr (expr);
583
590
584
591
// only do L1!
585
592
set_l1_indices (ssa, ns);
@@ -591,68 +598,144 @@ void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
591
598
ssa.type () = std::move (*renamed_type);
592
599
ssa.update_type ();
593
600
}
601
+
602
+ return std::move (ssa);
594
603
}
595
604
else if (expr.id ()==ID_symbol)
596
605
{
597
- expr=ssa_exprt (expr);
598
- rename_address<level>(expr, ns);
606
+ ssa_exprt ssa (expr);
607
+ if (auto renamed = rename_address<level>(ssa, ns))
608
+ return renamed;
609
+ else
610
+ return std::move (ssa);
599
611
}
600
- else
612
+ else if (expr. id () == ID_index)
601
613
{
602
- if (expr.id ()==ID_index)
603
- {
604
- index_exprt &index_expr=to_index_expr (expr);
614
+ const index_exprt &index_expr = to_index_expr (expr);
605
615
606
- rename_address<level>(index_expr.array (), ns);
607
- PRECONDITION (index_expr.array ().type ().id () == ID_array);
608
- expr.type () = to_array_type (index_expr.array ().type ()).subtype ();
616
+ auto renamed_array = rename_address<level>(index_expr.array (), ns);
609
617
610
- // the index is not an address
611
- index_expr. index () = rename <level>(std::move ( index_expr.index () ), ns);
612
- }
613
- else if (expr. id ()==ID_if )
618
+ // the index is not an address
619
+ auto renamed_index = rename <level>(index_expr.index (), ns);
620
+
621
+ if (renamed_array. has_value () || renamed_index != index_expr. index () )
614
622
{
615
- // the condition is not an address
616
- if_exprt &if_expr=to_if_expr (expr);
617
- if_expr.cond () = rename <level>(std::move (if_expr.cond ()), ns);
618
- rename_address<level>(if_expr.true_case (), ns);
619
- rename_address<level>(if_expr.false_case (), ns);
623
+ index_exprt result = index_expr;
624
+
625
+ if (renamed_array.has_value ())
626
+ {
627
+ result.array () = std::move (*renamed_array);
628
+ result.type () = to_array_type (result.array ().type ()).subtype ();
629
+ }
620
630
621
- if_expr.type ()=if_expr.true_case ().type ();
631
+ if (renamed_index != index_expr.index ())
632
+ result.index () = std::move (renamed_index);
633
+
634
+ return std::move (result);
622
635
}
623
- else if (expr.id ()==ID_member)
636
+ else
637
+ return {};
638
+ }
639
+ else if (expr.id () == ID_if)
640
+ {
641
+ // the condition is not an address
642
+ const if_exprt &if_expr = to_if_expr (expr);
643
+ auto renamed_cond = rename <level>(if_expr.cond (), ns);
644
+ auto renamed_true = rename_address<level>(if_expr.true_case (), ns);
645
+ auto renamed_false = rename_address<level>(if_expr.false_case (), ns);
646
+
647
+ if (
648
+ renamed_cond != if_expr.cond () || renamed_true.has_value () ||
649
+ renamed_false.has_value ())
624
650
{
625
- member_exprt &member_expr= to_member_expr (expr) ;
651
+ if_exprt result = if_expr ;
626
652
627
- rename_address<level>(member_expr.struct_op (), ns);
653
+ if (renamed_cond != if_expr.cond ())
654
+ result.cond () = std::move (renamed_cond);
628
655
629
- // type might not have been renamed in case of nesting of
630
- // structs and pointers/arrays
631
- if (
632
- member_expr.struct_op ().type ().id () != ID_symbol_type &&
633
- member_expr.struct_op ().type ().id () != ID_struct_tag &&
634
- member_expr.struct_op ().type ().id () != ID_union_tag)
656
+ if (renamed_true.has_value ())
635
657
{
636
- const struct_union_typet &su_type=
637
- to_struct_union_type (member_expr.struct_op ().type ());
638
- const struct_union_typet::componentt &comp=
639
- su_type.get_component (member_expr.get_component_name ());
640
- PRECONDITION (comp.is_not_nil ());
641
- expr.type ()=comp.type ();
658
+ result.true_case () = std::move (*renamed_true);
659
+ result.type () = result.true_case ().type ();
642
660
}
643
- else
644
- rename <level>(expr.type (), irep_idt (), ns);
661
+
662
+ if (renamed_false.has_value ())
663
+ result.false_case () = std::move (*renamed_false);
664
+
665
+ return std::move (result);
666
+ }
667
+ else
668
+ return {};
669
+ }
670
+ else if (expr.id () == ID_member)
671
+ {
672
+ const member_exprt &member_expr = to_member_expr (expr);
673
+
674
+ auto renamed_struct_op = rename_address<level>(member_expr.struct_op (), ns);
675
+
676
+ // type might not have been renamed in case of nesting of
677
+ // structs and pointers/arrays
678
+ optionalt<typet> renamed_type;
679
+ if (
680
+ renamed_struct_op.has_value () &&
681
+ renamed_struct_op->type ().id () != ID_symbol_type &&
682
+ renamed_struct_op->type ().id () != ID_struct_tag &&
683
+ renamed_struct_op->type ().id () != ID_union_tag)
684
+ {
685
+ const struct_union_typet &su_type =
686
+ to_struct_union_type (renamed_struct_op->type ());
687
+ const struct_union_typet::componentt &comp =
688
+ su_type.get_component (member_expr.get_component_name ());
689
+ PRECONDITION (comp.is_not_nil ());
690
+ renamed_type = comp.type ();
645
691
}
646
692
else
693
+ renamed_type = rename_type<level>(expr.type (), irep_idt (), ns);
694
+
695
+ if (renamed_struct_op.has_value () || renamed_type.has_value ())
696
+ {
697
+ member_exprt result = member_expr;
698
+
699
+ if (renamed_struct_op.has_value ())
700
+ result.struct_op () = std::move (*renamed_struct_op);
701
+
702
+ if (renamed_type.has_value ())
703
+ result.type () = std::move (*renamed_type);
704
+
705
+ return std::move (result);
706
+ }
707
+ else
708
+ return {};
709
+ }
710
+ else
711
+ {
712
+ exprt result = expr;
713
+ bool modified = false ;
714
+
715
+ // this could go wrong, but we would have to re-typecheck ...
716
+ if (auto renamed_type = rename_type<level>(expr.type (), irep_idt (), ns))
647
717
{
648
- // this could go wrong, but we would have to re-typecheck ...
649
- rename <level>(expr.type (), irep_idt (), ns);
718
+ result.type () = std::move (*renamed_type);
719
+ modified = true ;
720
+ }
650
721
651
- // do this recursively; we assume here
652
- // that all the operands are addresses
653
- Forall_operands (it, expr)
654
- rename_address<level>(*it, ns);
722
+ // do this recursively; we assume here
723
+ // that all the operands are addresses
724
+ exprt::operandst::iterator op_it = result.operands ().begin ();
725
+ forall_operands (it, expr)
726
+ {
727
+ if (auto renamed_op = rename_address<level>(*it, ns))
728
+ {
729
+ *op_it = std::move (*renamed_op);
730
+ modified = true ;
731
+ }
732
+ ++op_it;
655
733
}
734
+
735
+ if (modified)
736
+ return std::move (result);
737
+ else
738
+ return {};
656
739
}
657
740
}
658
741
0 commit comments