1212#include < util/nondet_bool.h>
1313#include < util/pointer_offset_size.h>
1414
15+ #include < goto-programs/class_identifier.h>
1516#include < goto-programs/goto_functions.h>
1617
18+ #include < linking/zero_initializer.h>
19+
1720#include " generic_parameter_specialization_map_keys.h"
1821#include " java_root_class.h"
1922
@@ -1027,8 +1030,35 @@ void java_object_factoryt::gen_nondet_struct_init(
10271030
10281031 const componentst &components=struct_type.components ();
10291032
1030- if (!is_sub)
1031- class_identifier=struct_tag;
1033+ // Should we write the whole object?
1034+ // * Not if this is a sub-structure (a superclass object), as our caller will
1035+ // have done this already
1036+ // * Not if the object has already been initialised by our caller, in whic
1037+ // case they will set `skip_classid`
1038+ // * Not if we're re-initializing an existing object (i.e. update_in_place)
1039+
1040+ if (!is_sub &&
1041+ !skip_classid &&
1042+ update_in_place != update_in_placet::MUST_UPDATE_IN_PLACE)
1043+ {
1044+ class_identifier = struct_tag;
1045+
1046+ // Add an initial all-zero write. Most of the fields of this will be
1047+ // overwritten, but it helps to have a whole-structure write that analysis
1048+ // passes can easily recognise leaves no uninitialised state behind.
1049+
1050+ // This code mirrors the `remove_java_new` pass:
1051+ null_message_handlert nullout;
1052+ exprt zero_object=
1053+ zero_initializer (
1054+ struct_type, source_locationt (), ns, nullout);
1055+ irep_idt qualified_clsid = " java::" + id2string (class_identifier);
1056+ set_class_identifier (
1057+ to_struct_expr (zero_object), ns, symbol_typet (qualified_clsid));
1058+
1059+ assignments.copy_to_operands (
1060+ code_assignt (expr, zero_object));
1061+ }
10321062
10331063 for (const auto &component : components)
10341064 {
@@ -1039,25 +1069,11 @@ void java_object_factoryt::gen_nondet_struct_init(
10391069
10401070 if (name==" @class_identifier" )
10411071 {
1042- if (update_in_place==update_in_placet::MUST_UPDATE_IN_PLACE)
1043- continue ;
1044-
1045- if (skip_classid)
1046- continue ;
1047-
1048- irep_idt qualified_clsid = " java::" + id2string (class_identifier);
1049- constant_exprt ci (qualified_clsid, string_typet ());
1050- code_assignt code (me, ci);
1051- code.add_source_location ()=loc;
1052- assignments.copy_to_operands (code);
1072+ continue ;
10531073 }
10541074 else if (name==" @lock" )
10551075 {
1056- if (update_in_place==update_in_placet::MUST_UPDATE_IN_PLACE)
1057- continue ;
1058- code_assignt code (me, from_integer (0 , me.type ()));
1059- code.add_source_location ()=loc;
1060- assignments.copy_to_operands (code);
1076+ continue ;
10611077 }
10621078 else
10631079 {
0 commit comments