@@ -126,6 +126,16 @@ class java_object_factoryt
126126 bool create_dynamic_objects,
127127 const pointer_typet &pointer_type,
128128 const update_in_placet &update_in_place);
129+
130+ void gen_nondet_struct_init (
131+ code_blockt &assignments,
132+ const exprt &expr,
133+ bool is_sub,
134+ irep_idt class_identifier,
135+ bool skip_classid,
136+ bool create_dynamic_objects,
137+ const struct_typet &struct_type,
138+ const update_in_placet &update_in_place);
129139};
130140
131141// / Generates code for allocating a dynamic object. This is used in
@@ -482,6 +492,98 @@ void java_object_factoryt::gen_nondet_pointer_init(
482492 }
483493}
484494
495+ // / Initialises an object tree rooted at `expr`, allocating child objects as
496+ // / necessary and nondet-initialising their members, or if MUST_UPDATE_IN_PLACE
497+ // / is set, re-initialising already-allocated objects.
498+ // / \param assignments: The code block to append the new
499+ // / instructions to
500+ // / \param expr: pointer-typed lvalue expression to initialise
501+ // / \param is_sub: If true, `expr` is a substructure of a larger object, which
502+ // / in Java necessarily means a base class. not match *expr (for example, expr
503+ // / might be void*)
504+ // / \param class_identifier: clsid to initialise @java.lang.Object.
505+ // / @class_identifier
506+ // / \param skip_classid: if true, skip initialising @class_identifier
507+ // / \param create_dynamic_objects: if true, use malloc to allocate objects;
508+ // / otherwise generate fresh static symbols.
509+ // / \param struct_type - The type of the struct we are initalising
510+ // / \param update_in_place: NO_UPDATE_IN_PLACE: initialise `expr` from scratch
511+ // / MUST_UPDATE_IN_PLACE: reinitialise an existing object MAY_UPDATE_IN_PLACE:
512+ // / invalid input
513+ void java_object_factoryt::gen_nondet_struct_init (
514+ code_blockt &assignments,
515+ const exprt &expr,
516+ bool is_sub,
517+ irep_idt class_identifier,
518+ bool skip_classid,
519+ bool create_dynamic_objects,
520+ const struct_typet &struct_type,
521+ const update_in_placet &update_in_place)
522+ {
523+ typedef struct_typet::componentst componentst;
524+ const irep_idt &struct_tag=struct_type.get_tag ();
525+
526+ const componentst &components=struct_type.components ();
527+
528+ if (!is_sub)
529+ class_identifier=struct_tag;
530+
531+ for (const auto &component : components)
532+ {
533+ const typet &component_type=component.type ();
534+ irep_idt name=component.get_name ();
535+
536+ member_exprt me (expr, name, component_type);
537+
538+ if (name==" @class_identifier" )
539+ {
540+ if (update_in_place==MUST_UPDATE_IN_PLACE)
541+ continue ;
542+
543+ if (skip_classid)
544+ continue ;
545+
546+ irep_idt qualified_clsid=" java::" +as_string (class_identifier);
547+ constant_exprt ci (qualified_clsid, string_typet ());
548+ code_assignt code (me, ci);
549+ code.add_source_location ()=loc;
550+ assignments.copy_to_operands (code);
551+ }
552+ else if (name==" @lock" )
553+ {
554+ if (update_in_place==MUST_UPDATE_IN_PLACE)
555+ continue ;
556+ code_assignt code (me, from_integer (0 , me.type ()));
557+ code.add_source_location ()=loc;
558+ assignments.copy_to_operands (code);
559+ }
560+ else
561+ {
562+ assert (!name.empty ());
563+
564+ bool _is_sub=name[0 ]==' @' ;
565+
566+ // MUST_UPDATE_IN_PLACE only applies to this object.
567+ // If this is a pointer to another object, offer the chance
568+ // to leave it alone by setting MAY_UPDATE_IN_PLACE instead.
569+ update_in_placet substruct_in_place=
570+ update_in_place==MUST_UPDATE_IN_PLACE && !_is_sub ?
571+ MAY_UPDATE_IN_PLACE :
572+ update_in_place;
573+ gen_nondet_init (
574+ assignments,
575+ me,
576+ _is_sub,
577+ class_identifier,
578+ false ,
579+ create_dynamic_objects,
580+ false ,
581+ typet (),
582+ substruct_in_place);
583+ }
584+ }
585+ }
586+
485587// / Initialises a primitive or object tree rooted at `expr`, allocating child
486588// / objects as necessary and nondet-initialising their members, or if
487589// / MUST_UPDATE_IN_PLACE is set, re-initialising already-allocated objects.
@@ -529,74 +631,16 @@ void java_object_factoryt::gen_nondet_init(
529631 }
530632 else if (type.id ()==ID_struct)
531633 {
532- typedef struct_typet::componentst componentst;
533-
534- const struct_typet &struct_type=to_struct_type (type);
535- const irep_idt struct_tag=struct_type.get_tag ();
536-
537- const componentst &components=struct_type.components ();
538-
539- if (!is_sub)
540- class_identifier=struct_tag;
541-
542- for (const auto &component : components)
543- {
544- const typet &component_type=component.type ();
545- irep_idt name=component.get_name ();
546-
547- member_exprt me (expr, name, component_type);
548-
549- if (name==" @class_identifier" )
550- {
551- if (update_in_place==MUST_UPDATE_IN_PLACE)
552- continue ;
553-
554- if (skip_classid)
555- continue ;
556-
557- irep_idt qualified_clsid=" java::" +as_string (class_identifier);
558- constant_exprt ci (qualified_clsid, string_typet ());
559- code_assignt code (me, ci);
560- code.add_source_location ()=loc;
561- assignments.copy_to_operands (code);
562- }
563- else if (name==" @lock" )
564- {
565- if (update_in_place==MUST_UPDATE_IN_PLACE)
566- continue ;
567- code_assignt code (me, from_integer (0 , me.type ()));
568- code.add_source_location ()=loc;
569- assignments.copy_to_operands (code);
570- }
571- else
572- {
573- assert (!name.empty ());
574-
575- bool _is_sub=name[0 ]==' @' ;
576- #if 0
577- irep_idt _class_identifier=
578- _is_sub?(class_identifier.empty()?struct_tag:class_identifier):"";
579- #endif
580-
581- // MUST_UPDATE_IN_PLACE only applies to this object.
582- // If this is a pointer to another object, offer the chance
583- // to leave it alone by setting MAY_UPDATE_IN_PLACE instead.
584- update_in_placet substruct_in_place=
585- update_in_place==MUST_UPDATE_IN_PLACE && !_is_sub ?
586- MAY_UPDATE_IN_PLACE :
587- update_in_place;
588- gen_nondet_init (
589- assignments,
590- me,
591- _is_sub,
592- class_identifier,
593- false ,
594- create_dynamic_objects,
595- false ,
596- typet (),
597- substruct_in_place);
598- }
599- }
634+ const struct_typet struct_type=to_struct_type (type);
635+ gen_nondet_struct_init (
636+ assignments,
637+ expr,
638+ is_sub,
639+ class_identifier,
640+ skip_classid,
641+ create_dynamic_objects,
642+ struct_type,
643+ update_in_place);
600644 }
601645 else
602646 {
0 commit comments