@@ -20,6 +20,7 @@ Date: April 2017
2020#include < util/allocate_objects.h>
2121#include < util/arith_tools.h>
2222#include < util/c_types.h>
23+ #include < util/expr_initializer.h>
2324#include < util/fresh_symbol.h>
2425#include < util/refined_string_type.h>
2526#include < util/std_code.h>
@@ -188,6 +189,17 @@ java_string_library_preprocesst::get_string_type_base_classes(
188189
189190 std::vector<irep_idt> bases;
190191 bases.reserve (3 );
192+
193+ // StringBuilder and StringBuffer derive from AbstractStringBuilder;
194+ // other String types (String and CharSequence) derive directly from Object.
195+ if (
196+ class_name == " java.lang.StringBuilder" ||
197+ class_name == " java.lang.StringBuffer" )
198+ bases.push_back (" java.lang.AbstractStringBuilder" );
199+ else
200+ bases.push_back (" java.lang.Object" );
201+
202+ // Interfaces:
191203 if (class_name != " java.lang.CharSequence" )
192204 {
193205 bases.push_back (" java.io.Serializable" );
@@ -196,10 +208,6 @@ java_string_library_preprocesst::get_string_type_base_classes(
196208 if (class_name == " java.lang.String" )
197209 bases.push_back (" java.lang.Comparable" );
198210
199- if (class_name == " java.lang.StringBuilder" ||
200- class_name == " java.lang.StringBuffer" )
201- bases.push_back (" java.lang.AbstractStringBuilder" );
202-
203211 return bases;
204212}
205213
@@ -230,7 +238,6 @@ void java_string_library_preprocesst::add_string_type(
230238 new_string_type.set_tag (class_name);
231239 new_string_type.set_name (class_symbol_name);
232240 new_string_type.set_access (ID_public);
233- new_string_type.add_base (struct_tag_typet (" java::java.lang.Object" ));
234241
235242 std::vector<irep_idt> bases = get_string_type_base_classes (class_name);
236243 for (const irep_idt &base_name : bases)
@@ -247,10 +254,12 @@ void java_string_library_preprocesst::add_string_type(
247254 auto &string_type = to_java_class_type (string_symbol->type );
248255
249256 string_type.components ().resize (3 );
250- string_type.components ()[0 ].set_name (" @java.lang.Object" );
251- string_type.components ()[0 ].set_pretty_name (" @java.lang.Object" );
252- string_type.components ()[0 ].type () =
253- struct_tag_typet (" java::java.lang.Object" );
257+ const struct_tag_typet &supertype = string_type.bases ().front ().type ();
258+ irep_idt supertype_component_name =
259+ " @" + id2string (supertype.get_identifier ()).substr (6 );
260+ string_type.components ()[0 ].set_name (supertype_component_name);
261+ string_type.components ()[0 ].set_pretty_name (supertype_component_name);
262+ string_type.components ()[0 ].type () = supertype;
254263 string_type.components ()[1 ].set_name (" length" );
255264 string_type.components ()[1 ].set_pretty_name (" length" );
256265 string_type.components ()[1 ].type ()=string_length_type ();
@@ -794,14 +803,15 @@ codet java_string_library_preprocesst::code_assign_components_to_java_string(
794803
795804 if (is_constructor)
796805 {
797- // A String has a field Object with @clsid = String
798- struct_tag_typet jlo_tag (" java::java.lang.Object" );
799- struct_exprt jlo_init ({}, jlo_tag);
800- irep_idt clsid = get_tag (lhs.type ().subtype ());
806+ // Initialise the supertype with the appropriate classid:
801807 namespacet ns (symbol_table);
802- java_root_class_init (jlo_init, ns.follow_tag (jlo_tag), clsid);
803-
804- struct_exprt struct_rhs ({jlo_init, rhs_length, rhs_array}, deref.type ());
808+ const struct_typet &lhs_type = to_struct_type (ns.follow (deref.type ()));
809+ auto zero_base_object = *zero_initializer (
810+ lhs_type.components ().front ().type (), source_locationt{}, ns);
811+ set_class_identifier (
812+ to_struct_expr (zero_base_object), ns, to_struct_tag_type (deref.type ()));
813+ struct_exprt struct_rhs (
814+ {zero_base_object, rhs_length, rhs_array}, deref.type ());
805815 return code_assignt (checked_dereference (lhs), struct_rhs);
806816 }
807817 else
0 commit comments