@@ -59,6 +59,9 @@ class java_object_factoryt
5959
6060 allocate_objectst allocate_objects;
6161
62+ // / Log for reporting warnings and errors in object creation
63+ messaget log;
64+
6265 code_assignt get_null_assignment (
6366 const exprt &expr,
6467 const pointer_typet &ptr_type);
@@ -84,7 +87,8 @@ class java_object_factoryt
8487 const source_locationt &loc,
8588 const java_object_factory_parameterst _object_factory_parameters,
8689 symbol_table_baset &_symbol_table,
87- const select_pointer_typet &pointer_type_selector)
90+ const select_pointer_typet &pointer_type_selector,
91+ message_handlert &log)
8892 : loc(loc),
8993 object_factory_parameters (_object_factory_parameters),
9094 symbol_table(_symbol_table),
@@ -94,7 +98,8 @@ class java_object_factoryt
9498 ID_java,
9599 loc,
96100 object_factory_parameters.function_id,
97- symbol_table)
101+ symbol_table),
102+ log(log)
98103 {}
99104
100105 void gen_nondet_array_init (
@@ -104,7 +109,7 @@ class java_object_factoryt
104109 update_in_placet,
105110 const source_locationt &location);
106111
107- void gen_nondet_enum_init (
112+ bool gen_nondet_enum_init (
108113 code_blockt &assignments,
109114 const exprt &expr,
110115 const java_class_typet &java_class_type,
@@ -263,8 +268,8 @@ void java_object_factoryt::gen_pointer_target_init(
263268 }
264269 if (target_class_type.get_base (" java::java.lang.Enum" ))
265270 {
266- gen_nondet_enum_init (assignments, expr, target_class_type, location);
267- return ;
271+ if ( gen_nondet_enum_init (assignments, expr, target_class_type, location))
272+ return ;
268273 }
269274 }
270275
@@ -1435,20 +1440,31 @@ void java_object_factoryt::gen_nondet_array_init(
14351440// / int i = nondet(int);
14361441// / assume(0 < = i < $VALUES.length);
14371442// / expr = $VALUES[i];
1438- // / where $VALUES is a variable generated by the Java compiler that stores
1439- // / the array that is returned by Enum.values().
1440- void java_object_factoryt::gen_nondet_enum_init (
1443+ // / where $VALUES is a variable generated by the Java compiler and which gives
1444+ // / the possible values of a particular enum subtype (this is the same array
1445+ // / that is returned by Enum.values()).
1446+ // / This may fail if the $VALUES static field is not present. Ensuring that
1447+ // / field is in the symbol table when this method may be applicable is the
1448+ // / driver program's responsibility: for example, \ref ci_lazy_methods.cpp makes
1449+ // / some effort to retain this field when a stub method might refer to it.
1450+ // / \return true on success
1451+ bool java_object_factoryt::gen_nondet_enum_init (
14411452 code_blockt &assignments,
14421453 const exprt &expr,
14431454 const java_class_typet &java_class_type,
14441455 const source_locationt &location)
14451456{
14461457 const irep_idt &class_name = java_class_type.get_name ();
14471458 const irep_idt values_name = id2string (class_name) + " .$VALUES" ;
1448- INVARIANT (
1449- ns.get_symbol_table ().has_symbol (values_name),
1450- " The $VALUES array (populated by clinit_wrapper) should be in the "
1451- " symbol table" );
1459+ if (!ns.get_symbol_table ().has_symbol (values_name))
1460+ {
1461+ log.warning () << values_name
1462+ << " is missing, so the corresponding Enum "
1463+ " type will nondet initialised"
1464+ << messaget::eom;
1465+ return false ;
1466+ }
1467+
14521468 const symbolt &values = ns.lookup (values_name);
14531469
14541470 // Access members (length and data) of $VALUES array
@@ -1473,6 +1489,8 @@ void java_object_factoryt::gen_nondet_enum_init(
14731489 const dereference_exprt arraycellref (plus);
14741490 code_assignt enum_assign (expr, typecast_exprt (arraycellref, expr.type ()));
14751491 assignments.add (enum_assign);
1492+
1493+ return true ;
14761494}
14771495
14781496static void assert_type_consistency (const code_blockt &assignments)
@@ -1510,7 +1528,8 @@ exprt object_factory(
15101528 java_object_factory_parameterst parameters,
15111529 lifetimet lifetime,
15121530 const source_locationt &loc,
1513- const select_pointer_typet &pointer_type_selector)
1531+ const select_pointer_typet &pointer_type_selector,
1532+ message_handlert &log)
15141533{
15151534 irep_idt identifier=id2string (goto_functionst::entry_point ())+
15161535 " ::" +id2string (base_name);
@@ -1531,10 +1550,7 @@ exprt object_factory(
15311550 CHECK_RETURN (!moving_symbol_failed);
15321551
15331552 java_object_factoryt state (
1534- loc,
1535- parameters,
1536- symbol_table,
1537- pointer_type_selector);
1553+ loc, parameters, symbol_table, pointer_type_selector, log);
15381554 code_blockt assignments;
15391555 state.gen_nondet_init (
15401556 assignments,
@@ -1587,6 +1603,7 @@ exprt object_factory(
15871603// / MAY_UPDATE_IN_PLACE: generate a runtime nondet branch between the NO_
15881604// / and MUST_ cases.
15891605// / MUST_UPDATE_IN_PLACE: reinitialize an existing object
1606+ // / \param log: used to report object construction warnings and failures
15901607// / \return `init_code` gets an instruction sequence to initialize or
15911608// / reinitialize `expr` and child objects it refers to. `symbol_table` is
15921609// / modified with any new symbols created. This includes any necessary
@@ -1600,13 +1617,11 @@ void gen_nondet_init(
16001617 lifetimet lifetime,
16011618 const java_object_factory_parameterst &object_factory_parameters,
16021619 const select_pointer_typet &pointer_type_selector,
1603- update_in_placet update_in_place)
1620+ update_in_placet update_in_place,
1621+ message_handlert &log)
16041622{
16051623 java_object_factoryt state (
1606- loc,
1607- object_factory_parameters,
1608- symbol_table,
1609- pointer_type_selector);
1624+ loc, object_factory_parameters, symbol_table, pointer_type_selector, log);
16101625 code_blockt assignments;
16111626 state.gen_nondet_init (
16121627 assignments,
@@ -1634,7 +1649,8 @@ exprt object_factory(
16341649 symbol_tablet &symbol_table,
16351650 const java_object_factory_parameterst &object_factory_parameters,
16361651 lifetimet lifetime,
1637- const source_locationt &location)
1652+ const source_locationt &location,
1653+ message_handlert &log)
16381654{
16391655 select_pointer_typet pointer_type_selector;
16401656 return object_factory (
@@ -1645,7 +1661,8 @@ exprt object_factory(
16451661 object_factory_parameters,
16461662 lifetime,
16471663 location,
1648- pointer_type_selector);
1664+ pointer_type_selector,
1665+ log);
16491666}
16501667
16511668// / Call gen_nondet_init() above with a default (identity) pointer_type_selector
@@ -1657,7 +1674,8 @@ void gen_nondet_init(
16571674 bool skip_classid,
16581675 lifetimet lifetime,
16591676 const java_object_factory_parameterst &object_factory_parameters,
1660- update_in_placet update_in_place)
1677+ update_in_placet update_in_place,
1678+ message_handlert &log)
16611679{
16621680 select_pointer_typet pointer_type_selector;
16631681 gen_nondet_init (
@@ -1669,7 +1687,8 @@ void gen_nondet_init(
16691687 lifetime,
16701688 object_factory_parameters,
16711689 pointer_type_selector,
1672- update_in_place);
1690+ update_in_place,
1691+ log);
16731692}
16741693
16751694// / Adds a call for the given method to the end of `assignments` if the method
0 commit comments