@@ -647,39 +647,46 @@ static irep_idt get_if_cmp_operator(const irep_idt &stmt)
647
647
throw " unhandled java comparison instruction" ;
648
648
}
649
649
650
- static member_exprt
651
- to_member (const exprt &pointer, const exprt &fieldref, const namespacet &ns)
650
+ // / Build a member exprt for accessing a specific field that may come from a
651
+ // / base class.
652
+ // / \param pointer: The expression to access the field on.
653
+ // / \param field_reference: A getfield/setfield instruction produced by the
654
+ // / bytecode parser.
655
+ // / \param ns: Global namespace
656
+ // / \return A member expression accessing the field, through base class
657
+ // / components if necessary.
658
+ static member_exprt to_member (
659
+ const exprt &pointer,
660
+ const exprt &field_reference,
661
+ const namespacet &ns)
652
662
{
653
- struct_tag_typet class_type (fieldref .get (ID_class));
663
+ struct_tag_typet class_type (field_reference .get (ID_class));
654
664
655
665
const exprt typed_pointer =
656
666
typecast_exprt::conditional_cast (pointer, java_reference_type (class_type));
657
667
658
- const irep_idt &component_name = fieldref .get (ID_component_name);
668
+ const irep_idt &component_name = field_reference .get (ID_component_name);
659
669
660
670
exprt accessed_object = checked_dereference (typed_pointer, class_type);
671
+ const auto type_of = [&ns](const exprt &object) {
672
+ return to_struct_type (ns.follow (object.type ()));
673
+ };
661
674
662
675
// The field access is described as being against a particular type, but it
663
676
// may in fact belong to any ancestor type.
664
- while (1 )
677
+ while (type_of (accessed_object). get_component (component_name). is_nil () )
665
678
{
666
- struct_typet object_type =
667
- to_struct_type (ns.follow (accessed_object.type ()));
668
- auto component = object_type.get_component (component_name);
669
-
670
- if (component.is_not_nil ())
671
- return member_exprt (accessed_object, component);
672
-
673
- // Component not present: check the immediate parent type.
674
-
675
- const auto &components = object_type.components ();
679
+ const auto components = type_of (accessed_object).components ();
676
680
INVARIANT (
677
681
components.size () != 0 ,
678
682
" infer_opaque_type_fields should guarantee that a member access has a "
679
683
" corresponding field" );
680
684
685
+ // Base class access is always done through the first component
681
686
accessed_object = member_exprt (accessed_object, components.front ());
682
687
}
688
+ return member_exprt (
689
+ accessed_object, type_of (accessed_object).get_component (component_name));
683
690
}
684
691
685
692
// / Find all goto statements in 'repl' that target 'old_label' and redirect them
0 commit comments