@@ -350,9 +350,10 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
350
350
else if (expr.id ()==ID_address_of)
351
351
{
352
352
auto &address_of_expr = to_address_of_expr (expr);
353
- rename_address<level>(address_of_expr.object (), ns);
354
- to_pointer_type (expr.type ()).subtype () =
355
- as_const (address_of_expr).object ().type ();
353
+ auto renamed_object = rename_address<level>(address_of_expr.object (), ns);
354
+
355
+ if (renamed_object.has_value ())
356
+ expr = address_of_exprt{std::move (*renamed_object)};
356
357
}
357
358
else
358
359
{
@@ -551,12 +552,13 @@ bool goto_symex_statet::l2_thread_write_encoding(
551
552
}
552
553
553
554
template <levelt level>
554
- void goto_symex_statet::rename_address (exprt &expr, const namespacet &ns)
555
+ optionalt<exprt>
556
+ goto_symex_statet::rename_address (const exprt &expr, const namespacet &ns)
555
557
{
556
558
if (expr.id ()==ID_symbol &&
557
559
expr.get_bool (ID_C_SSA_symbol))
558
560
{
559
- ssa_exprt & ssa= to_ssa_expr (expr);
561
+ ssa_exprt ssa = to_ssa_expr (expr);
560
562
561
563
// only do L1!
562
564
ssa = set_indices<L1>(std::move (ssa), ns).get ();
@@ -568,67 +570,151 @@ void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
568
570
ssa.type () = std::move (*renamed_type);
569
571
ssa.update_type ();
570
572
}
573
+
574
+ return std::move (ssa);
571
575
}
572
576
else if (expr.id ()==ID_symbol)
573
577
{
574
- expr=ssa_exprt (expr);
575
- rename_address<level>(expr, ns);
578
+ ssa_exprt ssa{expr};
579
+ if (auto renamed = rename_address<level>(ssa, ns))
580
+ return renamed;
581
+ else
582
+ return std::move (ssa);
576
583
}
577
- else
584
+ else if (expr. id () == ID_index)
578
585
{
579
- if (expr.id ()==ID_index)
586
+ const index_exprt &index_expr = to_index_expr (expr);
587
+
588
+ auto renamed_array = rename_address<level>(index_expr.array (), ns);
589
+
590
+ // the index is not an address
591
+ auto renamed_index = rename <level>(index_expr.index (), ns);
592
+
593
+ if (renamed_array.has_value () || renamed_index != index_expr.index ())
580
594
{
581
- index_exprt &index_expr=to_index_expr (expr);
595
+ index_exprt result = index_expr;
596
+
597
+ if (renamed_array.has_value ())
598
+ {
599
+ result.array () = std::move (*renamed_array);
600
+ result.type () = to_array_type (result.array ().type ()).subtype ();
601
+ }
602
+
603
+ if (renamed_index != index_expr.index ())
604
+ result.index () = std::move (renamed_index);
605
+
606
+ return std::move (result);
607
+ }
608
+ else
609
+ return {};
610
+ }
611
+ else if (expr.id () == ID_if)
612
+ {
613
+ // the condition is not an address
614
+ const if_exprt &if_expr = to_if_expr (expr);
615
+ auto renamed_cond = rename <level>(if_expr.cond (), ns);
616
+ auto renamed_true = rename_address<level>(if_expr.true_case (), ns);
617
+ auto renamed_false = rename_address<level>(if_expr.false_case (), ns);
618
+
619
+ if (
620
+ renamed_cond != if_expr.cond () || renamed_true.has_value () ||
621
+ renamed_false.has_value ())
622
+ {
623
+ if_exprt result = if_expr;
624
+
625
+ if (renamed_cond != if_expr.cond ())
626
+ result.cond () = std::move (renamed_cond);
627
+
628
+ if (renamed_true.has_value ())
629
+ {
630
+ result.true_case () = std::move (*renamed_true);
631
+ result.type () = result.true_case ().type ();
632
+ }
633
+
634
+ if (renamed_false.has_value ())
635
+ result.false_case () = std::move (*renamed_false);
582
636
583
- rename_address<level>(index_expr.array (), ns);
584
- PRECONDITION (index_expr.array ().type ().id () == ID_array);
585
- expr.type () = to_array_type (index_expr.array ().type ()).subtype ();
637
+ return std::move (result);
638
+ }
639
+ else
640
+ return {};
641
+ }
642
+ else if (expr.id () == ID_member)
643
+ {
644
+ const member_exprt &member_expr = to_member_expr (expr);
586
645
587
- // the index is not an address
588
- index_expr.index () = rename <level>(std::move (index_expr.index ()), ns);
646
+ auto renamed_struct_op = rename_address<level>(member_expr.struct_op (), ns);
647
+
648
+ // type might not have been renamed in case of nesting of
649
+ // structs and pointers/arrays
650
+ optionalt<typet> renamed_type;
651
+ if (
652
+ renamed_struct_op.has_value () &&
653
+ renamed_struct_op->type ().id () != ID_struct_tag &&
654
+ renamed_struct_op->type ().id () != ID_union_tag)
655
+ {
656
+ const struct_union_typet &su_type =
657
+ to_struct_union_type (renamed_struct_op->type ());
658
+ const struct_union_typet::componentt &comp =
659
+ su_type.get_component (member_expr.get_component_name ());
660
+ DATA_INVARIANT (comp.is_not_nil (), " component should exist" );
661
+ renamed_type = comp.type ();
589
662
}
590
- else if (expr.id ()==ID_if)
663
+ else
664
+ renamed_type = rename_type<level>(expr.type (), irep_idt (), ns);
665
+
666
+ if (renamed_struct_op.has_value () || renamed_type.has_value ())
591
667
{
592
- // the condition is not an address
593
- if_exprt &if_expr=to_if_expr (expr);
594
- if_expr.cond () = rename <level>(std::move (if_expr.cond ()), ns);
595
- rename_address<level>(if_expr.true_case (), ns);
596
- rename_address<level>(if_expr.false_case (), ns);
668
+ member_exprt result = member_expr;
669
+
670
+ if (renamed_struct_op.has_value ())
671
+ result.struct_op () = std::move (*renamed_struct_op);
597
672
598
- if_expr.type ()=if_expr.true_case ().type ();
673
+ if (renamed_type.has_value ())
674
+ result.type () = std::move (*renamed_type);
675
+
676
+ return std::move (result);
599
677
}
600
- else if (expr.id ()==ID_member)
678
+ else
679
+ return {};
680
+ }
681
+ else
682
+ {
683
+ optionalt<exprt> result;
684
+
685
+ // this could go wrong, but we would have to re-typecheck ...
686
+ if (auto renamed_type = rename_type<level>(expr.type (), irep_idt (), ns))
601
687
{
602
- member_exprt &member_expr=to_member_expr (expr);
688
+ result = expr;
689
+ result->type () = std::move (*renamed_type);
690
+ }
603
691
604
- rename_address<level>(member_expr.struct_op (), ns);
692
+ // do this recursively; we assume here
693
+ // that all the operands are addresses
694
+ optionalt<exprt::operandst> result_operands;
695
+ std::size_t op_index = 0 ;
605
696
606
- // type might not have been renamed in case of nesting of
607
- // structs and pointers/arrays
608
- if (
609
- member_expr.struct_op ().type ().id () != ID_struct_tag &&
610
- member_expr.struct_op ().type ().id () != ID_union_tag)
697
+ for (auto &op : expr.operands ())
698
+ {
699
+ if (auto renamed_op = rename_address<level>(op, ns))
611
700
{
612
- const struct_union_typet &su_type=
613
- to_struct_union_type (member_expr.struct_op ().type ());
614
- const struct_union_typet::componentt &comp=
615
- su_type.get_component (member_expr.get_component_name ());
616
- PRECONDITION (comp.is_not_nil ());
617
- expr.type ()=comp.type ();
701
+ if (!result_operands.has_value ())
702
+ result_operands = expr.operands ();
703
+
704
+ (*result_operands)[op_index] = std::move (*renamed_op);
618
705
}
619
- else
620
- rename <level>(expr.type (), irep_idt (), ns);
706
+ ++op_index;
621
707
}
622
- else
708
+
709
+ if (result_operands.has_value ())
623
710
{
624
- // this could go wrong, but we would have to re-typecheck ...
625
- rename <level>(expr. type (), irep_idt (), ns) ;
711
+ if (!result. has_value ())
712
+ result = expr ;
626
713
627
- // do this recursively; we assume here
628
- // that all the operands are addresses
629
- Forall_operands (it, expr)
630
- rename_address<level>(*it, ns);
714
+ result->operands () = std::move (*result_operands);
631
715
}
716
+
717
+ return result;
632
718
}
633
719
}
634
720
0 commit comments