25
25
#include " java_bytecode_convert_method.h"
26
26
#include " java_bytecode_convert_method_class.h"
27
27
#include " bytecode_info.h"
28
+ #include " java_object_factory.h"
29
+ #include " java_root_class.h"
28
30
#include " java_types.h"
29
31
30
32
#include < limits>
@@ -569,53 +571,105 @@ codet java_bytecode_convert_methodt::get_array_bounds_check(
569
571
570
572
/* ******************************************************************\
571
573
572
- Function: throw_array_access_exception
574
+ Function: throw_exception
573
575
574
576
Inputs:
575
577
576
578
Outputs:
577
579
578
- Purpose: Checks whether the array access array_struct[idx]
579
- is out-of-bounds, and throws ArrayIndexOutofBoundsException
580
- if necessary
580
+ Purpose: Creates a class stub for exc_name and generates a
581
+ conditional GOTO such that exc_name is thrown when
582
+ cond is met
581
583
582
584
\*******************************************************************/
583
585
584
- codet java_bytecode_convert_methodt::throw_array_access_exception (
585
- const exprt &array_struct ,
586
- const exprt &idx ,
587
- const source_locationt &original_loc )
586
+ codet java_bytecode_convert_methodt::throw_exception (
587
+ const exprt &cond ,
588
+ const source_locationt &original_loc ,
589
+ const irep_idt &exc_name )
588
590
{
589
- symbolt exc_symbol;
590
- if (!symbol_table.has_symbol (" ArrayIndexOutOfBoundsException" ))
591
+ exprt exc;
592
+ code_blockt init_code;
593
+ const irep_idt &exc_obj_name=id2string (goto_functionst::entry_point ())+
594
+ " ::" +id2string (exc_name);
595
+
596
+ if (!symbol_table.has_symbol (exc_obj_name))
591
597
{
592
- exc_symbol.is_static_lifetime =true ;
593
- exc_symbol.base_name =" ArrayIndexOutOfBoundsException" ;
594
- exc_symbol.name =" ArrayIndexOutOfBoundsException" ;
598
+ // for now, create a class stub
599
+ // TODO: model exceptions and use that model
600
+ class_typet class_type;
601
+ class_type.set_tag (exc_name);
602
+ class_type.set (ID_base_name, exc_name);
603
+ class_type.set (ID_incomplete_class, true );
604
+
605
+ // produce class symbol
606
+ symbolt exc_symbol;
607
+ exc_symbol.base_name =exc_name;
608
+ exc_symbol.pretty_name =exc_name;
609
+ exc_symbol.name =" java::" +id2string (exc_name);
610
+ class_type.set (ID_name, exc_symbol.name );
611
+ exc_symbol.type =class_type;
595
612
exc_symbol.mode =ID_java;
596
- exc_symbol.type = typet (ID_pointer, empty_typet ()) ;
613
+ exc_symbol.is_type = true ;
597
614
symbol_table.add (exc_symbol);
615
+ // create the class identifier
616
+ java_root_class (exc_symbol);
617
+
618
+ // create the exception object
619
+ exc=object_factory (
620
+ pointer_typet (exc_symbol.type ),
621
+ exc_name,
622
+ init_code,
623
+ false ,
624
+ symbol_table,
625
+ max_array_length,
626
+ original_loc);
598
627
}
599
628
else
600
- exc_symbol =symbol_table.lookup (" ArrayIndexOutOfBoundsException " );
629
+ exc =symbol_table.lookup (exc_obj_name). symbol_expr ( );
601
630
602
- const symbol_exprt &exc=exc_symbol.symbol_expr ();
603
631
side_effect_expr_throwt throw_expr;
604
632
throw_expr.add_source_location ()=original_loc;
605
- throw_expr.copy_to_operands (exc);
633
+ throw_expr.move_to_operands (exc);
634
+
635
+ code_ifthenelset if_code;
636
+ if_code.add_source_location ()=original_loc;
637
+ if_code.cond ()=cond;
638
+ if_code.then_case ()=code_expressiont (throw_expr);
639
+
640
+ init_code.move_to_operands (if_code);
641
+
642
+ return init_code;
643
+ }
644
+
645
+ /* ******************************************************************\
646
+
647
+ Function: throw_array_access_exception
648
+
649
+ Inputs:
650
+
651
+ Outputs:
606
652
653
+ Purpose: Checks whether the array access array_struct[idx]
654
+ is out-of-bounds, and throws ArrayIndexOutofBoundsException
655
+ if necessary
656
+
657
+ \*******************************************************************/
658
+
659
+ codet java_bytecode_convert_methodt::throw_array_access_exception (
660
+ const exprt &array_struct,
661
+ const exprt &idx,
662
+ const source_locationt &original_loc)
663
+ {
607
664
const constant_exprt &zero=from_integer (0 , java_int_type ());
608
665
const binary_relation_exprt lt_zero (idx, ID_lt, zero);
609
666
const member_exprt length_field (array_struct, " length" , java_int_type ());
610
667
const binary_relation_exprt ge_length (idx, ID_ge, length_field);
611
- const and_exprt and_expr (lt_zero, ge_length);
668
+ const or_exprt or_expr (lt_zero, ge_length);
612
669
613
- code_ifthenelset if_code;
614
- if_code.add_source_location ()=original_loc;
615
- if_code.cond ()=and_expr;
616
- if_code.then_case ()=code_expressiont (throw_expr);
617
-
618
- return if_code;
670
+ return throw_exception (
671
+ or_expr,
672
+ original_loc, " java.lang.ArrayIndexOutOfBoundsException" );
619
673
}
620
674
621
675
/* ******************************************************************\
@@ -634,33 +688,12 @@ codet java_bytecode_convert_methodt::throw_array_length_exception(
634
688
const exprt &length,
635
689
const source_locationt &original_loc)
636
690
{
637
- symbolt exc_symbol;
638
- if (!symbol_table.has_symbol (" NegativeArraySizeException" ))
639
- {
640
- exc_symbol.is_static_lifetime =true ;
641
- exc_symbol.base_name =" NegativeArraySizeException" ;
642
- exc_symbol.name =" NegativeArraySizeException" ;
643
- exc_symbol.mode =ID_java;
644
- exc_symbol.type =typet (ID_pointer, empty_typet ());
645
- symbol_table.add (exc_symbol);
646
- }
647
- else
648
- exc_symbol=symbol_table.lookup (" NegativeArraySizeException" );
649
-
650
- const symbol_exprt &exc=exc_symbol.symbol_expr ();
651
- side_effect_expr_throwt throw_expr;
652
- throw_expr.add_source_location ()=original_loc;
653
- throw_expr.copy_to_operands (exc);
654
-
655
691
const constant_exprt &zero=from_integer (0 , java_int_type ());
656
- const binary_relation_exprt ge_zero (length, ID_ge, zero);
657
-
658
- code_ifthenelset if_code;
659
- if_code.add_source_location ()=original_loc;
660
- if_code.cond ()=ge_zero;
661
- if_code.then_case ()=code_expressiont (throw_expr);
692
+ const binary_relation_exprt less_zero (length, ID_lt, zero);
662
693
663
- return if_code;
694
+ return throw_exception (
695
+ less_zero,
696
+ original_loc, " java.lang.NegativeArraySizeException" );
664
697
}
665
698
666
699
/* ******************************************************************\
@@ -677,36 +710,22 @@ Function: throw_null_dereference_exception
677
710
\*******************************************************************/
678
711
679
712
codet java_bytecode_convert_methodt::throw_null_dereference_exception (
680
- const exprt &expr,
713
+ exprt &expr,
681
714
const source_locationt &original_loc)
682
715
{
683
- symbolt exc_symbol;
684
- if (!symbol_table.has_symbol (" NullPointerException" ))
685
- {
686
- exc_symbol.is_static_lifetime =true ;
687
- exc_symbol.base_name =" NullPointerException" ;
688
- exc_symbol.name =" NullPointerException" ;
689
- exc_symbol.mode =ID_java;
690
- exc_symbol.type =typet (ID_pointer, empty_typet ());
691
- symbol_table.add (exc_symbol);
692
- }
693
- else
694
- exc_symbol=symbol_table.lookup (" NullPointerException" );
716
+ empty_typet voidt;
717
+ pointer_typet voidptr (voidt);
695
718
696
- const symbol_exprt &exc=exc_symbol.symbol_expr ();
697
- side_effect_expr_throwt throw_expr;
698
- throw_expr.add_source_location ()=original_loc;
699
- throw_expr.copy_to_operands (exc);
719
+ if (expr.type ()!=voidptr)
720
+ expr.make_typecast (voidptr);
700
721
701
722
const equal_exprt equal_expr (
702
723
expr,
703
- null_pointer_exprt (pointer_typet (empty_typet ())));
704
- code_ifthenelset if_code;
705
- if_code.add_source_location ()=original_loc;
706
- if_code.cond ()=equal_expr;
707
- if_code.then_case ()=code_expressiont (throw_expr);
724
+ null_pointer_exprt (voidptr));
708
725
709
- return if_code;
726
+ return throw_exception (
727
+ equal_expr,
728
+ original_loc, " java.lang.NullPointerException" );
710
729
}
711
730
712
731
/* ******************************************************************\
@@ -726,26 +745,6 @@ codet java_bytecode_convert_methodt::throw_class_cast_exception(
726
745
const exprt &class2,
727
746
const source_locationt &original_loc)
728
747
{
729
- // TODO: use std::move
730
- symbolt exc_symbol;
731
- if (!symbol_table.has_symbol (" ClassCastException" ))
732
- {
733
- exc_symbol.is_static_lifetime =true ;
734
- exc_symbol.base_name =" ClassCastException" ;
735
- exc_symbol.name =" ClassCastException" ;
736
- exc_symbol.mode =ID_java;
737
- exc_symbol.type =typet (ID_pointer, empty_typet ());
738
- symbol_table.add (exc_symbol);
739
- }
740
- else
741
- exc_symbol=symbol_table.lookup (" ClassCastException" );
742
-
743
- const symbol_exprt &exc=exc_symbol.symbol_expr ();
744
-
745
- side_effect_expr_throwt throw_expr;
746
- throw_expr.add_source_location ()=original_loc;
747
- throw_expr.copy_to_operands (exc);
748
-
749
748
binary_predicate_exprt class_cast_check (
750
749
class1, ID_java_instanceof, class2);
751
750
@@ -757,14 +756,12 @@ codet java_bytecode_convert_methodt::throw_class_cast_exception(
757
756
notequal_exprt op_not_null (null_check_op, null_pointer_exprt (voidptr));
758
757
759
758
// checkcast passes when the operand is null
760
- and_exprt and_expr (op_not_null, class_cast_check);
761
-
762
- code_ifthenelset if_code;
763
- if_code.add_source_location ()=original_loc;
764
- if_code.cond ()=and_expr;
765
- if_code.then_case ()=code_expressiont (throw_expr);
759
+ and_exprt and_expr (op_not_null, not_exprt (class_cast_check));
766
760
767
- return if_code;
761
+ return throw_exception (
762
+ and_expr,
763
+ original_loc,
764
+ " ClassCastException" );
768
765
}
769
766
770
767
/* ******************************************************************\
@@ -1596,6 +1593,7 @@ codet java_bytecode_convert_methodt::convert_instructions(
1596
1593
// on stack to given type fails.
1597
1594
// The stack isn't modified.
1598
1595
assert (op.size ()==1 && results.size ()==1 );
1596
+
1599
1597
if (throw_runtime_exceptions)
1600
1598
{
1601
1599
codet conditional_check=
@@ -1845,6 +1843,7 @@ codet java_bytecode_convert_methodt::convert_instructions(
1845
1843
const dereference_exprt element (data_plus_offset, element_type);
1846
1844
1847
1845
c=code_blockt ();
1846
+
1848
1847
codet bounds_check=throw_runtime_exceptions?
1849
1848
throw_array_access_exception (deref, op[1 ], i_it->source_location ):
1850
1849
get_array_bounds_check (deref, op[1 ], i_it->source_location );
@@ -2333,6 +2332,14 @@ codet java_bytecode_convert_methodt::convert_instructions(
2333
2332
else if (statement==" getfield" )
2334
2333
{
2335
2334
assert (op.size ()==1 && results.size ()==1 );
2335
+ if (throw_runtime_exceptions)
2336
+ {
2337
+ codet null_dereference_check=
2338
+ throw_null_dereference_exception (
2339
+ op[0 ],
2340
+ i_it->source_location );
2341
+ c=null_dereference_check;
2342
+ }
2336
2343
results[0 ]=java_bytecode_promotion (to_member (op[0 ], arg0));
2337
2344
}
2338
2345
else if (statement==" getstatic" )
@@ -2360,6 +2367,14 @@ codet java_bytecode_convert_methodt::convert_instructions(
2360
2367
else if (statement==" putfield" )
2361
2368
{
2362
2369
assert (op.size ()==2 && results.size ()==0 );
2370
+ if (throw_runtime_exceptions)
2371
+ {
2372
+ codet null_dereference_check=
2373
+ throw_null_dereference_exception (
2374
+ op[0 ],
2375
+ i_it->source_location );
2376
+ c=null_dereference_check;
2377
+ }
2363
2378
c=code_assignt (to_member (op[0 ], arg0), op[1 ]);
2364
2379
}
2365
2380
else if (statement==" putstatic" )
0 commit comments