@@ -539,216 +539,6 @@ void goto_convertt::do_cpp_new(
539539 dest.destructive_append (tmp_initializer);
540540}
541541
542- void goto_convertt::do_java_new (
543- const exprt &lhs,
544- const side_effect_exprt &rhs,
545- goto_programt &dest)
546- {
547- PRECONDITION (!lhs.is_nil ());
548- PRECONDITION (rhs.operands ().empty ());
549- PRECONDITION (rhs.type ().id () == ID_pointer);
550- source_locationt location=rhs.source_location ();
551- typet object_type=rhs.type ().subtype ();
552-
553- // build size expression
554- exprt object_size=size_of_expr (object_type, ns);
555- CHECK_RETURN (object_size.is_not_nil ());
556-
557- // we produce a malloc side-effect, which stays
558- side_effect_exprt malloc_expr (ID_allocate, rhs.type ());
559- malloc_expr.copy_to_operands (object_size);
560- // could use true and get rid of the code below
561- malloc_expr.copy_to_operands (false_exprt ());
562-
563- goto_programt::targett t_n=dest.add_instruction (ASSIGN);
564- t_n->code =code_assignt (lhs, malloc_expr);
565- t_n->source_location =location;
566-
567- // zero-initialize the object
568- dereference_exprt deref (lhs, object_type);
569- exprt zero_object=
570- zero_initializer (object_type, location, ns, get_message_handler ());
571- set_class_identifier (
572- to_struct_expr (zero_object), ns, to_symbol_type (object_type));
573- goto_programt::targett t_i=dest.add_instruction (ASSIGN);
574- t_i->code =code_assignt (deref, zero_object);
575- t_i->source_location =location;
576- }
577-
578- void goto_convertt::do_java_new_array (
579- const exprt &lhs,
580- const side_effect_exprt &rhs,
581- goto_programt &dest)
582- {
583- PRECONDITION (!lhs.is_nil ()); // do_java_new_array without lhs not implemented
584- PRECONDITION (rhs.operands ().size () >= 1 ); // one per dimension
585- PRECONDITION (rhs.type ().id () == ID_pointer);
586-
587- source_locationt location=rhs.source_location ();
588- typet object_type=rhs.type ().subtype ();
589- PRECONDITION (ns.follow (object_type).id () == ID_struct);
590-
591- // build size expression
592- exprt object_size=size_of_expr (object_type, ns);
593-
594- CHECK_RETURN (!object_size.is_nil ());
595-
596- // we produce a malloc side-effect, which stays
597- side_effect_exprt malloc_expr (ID_allocate, rhs.type ());
598- malloc_expr.copy_to_operands (object_size);
599- // code use true and get rid of the code below
600- malloc_expr.copy_to_operands (false_exprt ());
601-
602- goto_programt::targett t_n=dest.add_instruction (ASSIGN);
603- t_n->code =code_assignt (lhs, malloc_expr);
604- t_n->source_location =location;
605-
606- const struct_typet &struct_type=to_struct_type (ns.follow (object_type));
607-
608- // Ideally we would have a check for `is_valid_java_array(struct_type)` but
609- // `is_valid_java_array is part of the java_bytecode module and we cannot
610- // introduce such dependencies. We do this simple check instead:
611- PRECONDITION (struct_type.components ().size ()==3 );
612-
613- // Init base class:
614- dereference_exprt deref (lhs, object_type);
615- exprt zero_object=
616- zero_initializer (object_type, location, ns, get_message_handler ());
617- set_class_identifier (
618- to_struct_expr (zero_object), ns, to_symbol_type (object_type));
619- goto_programt::targett t_i=dest.add_instruction (ASSIGN);
620- t_i->code =code_assignt (deref, zero_object);
621- t_i->source_location =location;
622-
623- // if it's an array, we need to set the length field
624- member_exprt length (
625- deref,
626- struct_type.components ()[1 ].get_name (),
627- struct_type.components ()[1 ].type ());
628- goto_programt::targett t_s=dest.add_instruction (ASSIGN);
629- t_s->code =code_assignt (length, rhs.op0 ());
630- t_s->source_location =location;
631-
632- // we also need to allocate space for the data
633- member_exprt data (
634- deref,
635- struct_type.components ()[2 ].get_name (),
636- struct_type.components ()[2 ].type ());
637-
638- // Allocate a (struct realtype**) instead of a (void**) if possible.
639- const irept &given_element_type=object_type.find (ID_C_element_type);
640- typet allocate_data_type;
641- if (given_element_type.is_not_nil ())
642- {
643- allocate_data_type=
644- pointer_type (static_cast <const typet &>(given_element_type));
645- }
646- else
647- allocate_data_type=data.type ();
648-
649- side_effect_exprt data_java_new_expr (
650- ID_java_new_array_data, allocate_data_type);
651-
652- // The instruction may specify a (hopefully small) upper bound on the
653- // array size, in which case we allocate a fixed-length array that may
654- // be larger than the `length` member rather than use a true variable-
655- // length array, which produces a more complex formula in the current
656- // backend.
657- const irept size_bound=rhs.find (ID_length_upper_bound);
658- if (size_bound.is_nil ())
659- data_java_new_expr.set (ID_size, rhs.op0 ());
660- else
661- data_java_new_expr.set (ID_size, size_bound);
662-
663- // Must directly assign the new array to a temporary
664- // because goto-symex will notice `x=side_effect_exprt` but not
665- // `x=typecast_exprt(side_effect_exprt(...))`
666- symbol_exprt new_array_data_symbol =
667- new_tmp_symbol (
668- data_java_new_expr.type (), " new_array_data" , dest, location, ID_java)
669- .symbol_expr ();
670- goto_programt::targett t_p2=dest.add_instruction (ASSIGN);
671- t_p2->code =code_assignt (new_array_data_symbol, data_java_new_expr);
672- t_p2->source_location =location;
673-
674- goto_programt::targett t_p=dest.add_instruction (ASSIGN);
675- exprt cast_java_new=new_array_data_symbol;
676- if (cast_java_new.type ()!=data.type ())
677- cast_java_new=typecast_exprt (cast_java_new, data.type ());
678- t_p->code =code_assignt (data, cast_java_new);
679- t_p->source_location =location;
680-
681- // zero-initialize the data
682- if (!rhs.get_bool (ID_skip_initialize))
683- {
684- exprt zero_element=
685- zero_initializer (
686- data.type ().subtype (),
687- location,
688- ns,
689- get_message_handler ());
690- codet array_set (ID_array_set);
691- array_set.copy_to_operands (new_array_data_symbol, zero_element);
692- goto_programt::targett t_d=dest.add_instruction (OTHER);
693- t_d->code =array_set;
694- t_d->source_location =location;
695- }
696-
697- // multi-dimensional?
698-
699- if (rhs.operands ().size ()>=2 )
700- {
701- // produce
702- // for(int i=0; i<size; i++) tmp[i]=java_new(dim-1);
703- // This will be converted recursively.
704-
705- goto_programt tmp;
706-
707- symbol_exprt tmp_i =
708- new_tmp_symbol (length.type (), " index" , tmp, location, ID_java)
709- .symbol_expr ();
710-
711- code_fort for_loop;
712-
713- side_effect_exprt sub_java_new=rhs;
714- sub_java_new.operands ().erase (sub_java_new.operands ().begin ());
715-
716- assert (rhs.type ().id ()==ID_pointer);
717- typet sub_type=
718- static_cast <const typet &>(rhs.type ().subtype ().find (" #element_type" ));
719- assert (sub_type.id ()==ID_pointer);
720- sub_java_new.type ()=sub_type;
721-
722- side_effect_exprt inc (ID_assign);
723- inc.operands ().resize (2 );
724- inc.op0 ()=tmp_i;
725- inc.op1 ()=plus_exprt (tmp_i, from_integer (1 , tmp_i.type ()));
726-
727- dereference_exprt deref_expr (
728- plus_exprt (data, tmp_i), data.type ().subtype ());
729-
730- code_blockt for_body;
731- symbol_exprt init_sym =
732- new_tmp_symbol (sub_type, " subarray_init" , tmp, location, ID_java)
733- .symbol_expr ();
734-
735- code_assignt init_subarray (init_sym, sub_java_new);
736- code_assignt assign_subarray (
737- deref_expr,
738- typecast_exprt (init_sym, deref_expr.type ()));
739- for_body.move_to_operands (init_subarray);
740- for_body.move_to_operands (assign_subarray);
741-
742- for_loop.init ()=code_assignt (tmp_i, from_integer (0 , tmp_i.type ()));
743- for_loop.cond ()=binary_relation_exprt (tmp_i, ID_lt, rhs.op0 ());
744- for_loop.iter ()=inc;
745- for_loop.body ()=for_body;
746-
747- convert (for_loop, tmp);
748- dest.destructive_append (tmp);
749- }
750- }
751-
752542// / builds a goto program for object initialization after new
753543void goto_convertt::cpp_new_initializer (
754544 const exprt &lhs,
0 commit comments