@@ -539,216 +539,6 @@ void goto_convertt::do_cpp_new(
539
539
dest.destructive_append (tmp_initializer);
540
540
}
541
541
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
-
752
542
// / builds a goto program for object initialization after new
753
543
void goto_convertt::cpp_new_initializer (
754
544
const exprt &lhs,
0 commit comments