@@ -59,6 +59,9 @@ class java_object_factoryt
59
59
60
60
allocate_objectst allocate_objects;
61
61
62
+ // / Log for reporting warnings and errors in object creation
63
+ messaget log;
64
+
62
65
code_assignt get_null_assignment (
63
66
const exprt &expr,
64
67
const pointer_typet &ptr_type);
@@ -84,7 +87,8 @@ class java_object_factoryt
84
87
const source_locationt &loc,
85
88
const java_object_factory_parameterst _object_factory_parameters,
86
89
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)
88
92
: loc(loc),
89
93
object_factory_parameters (_object_factory_parameters),
90
94
symbol_table(_symbol_table),
@@ -94,7 +98,8 @@ class java_object_factoryt
94
98
ID_java,
95
99
loc,
96
100
object_factory_parameters.function_id,
97
- symbol_table)
101
+ symbol_table),
102
+ log(log)
98
103
{}
99
104
100
105
void gen_nondet_array_init (
@@ -104,7 +109,7 @@ class java_object_factoryt
104
109
update_in_placet,
105
110
const source_locationt &location);
106
111
107
- void gen_nondet_enum_init (
112
+ bool gen_nondet_enum_init (
108
113
code_blockt &assignments,
109
114
const exprt &expr,
110
115
const java_class_typet &java_class_type,
@@ -263,8 +268,8 @@ void java_object_factoryt::gen_pointer_target_init(
263
268
}
264
269
if (target_class_type.get_base (" java::java.lang.Enum" ))
265
270
{
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 ;
268
273
}
269
274
}
270
275
@@ -1435,20 +1440,31 @@ void java_object_factoryt::gen_nondet_array_init(
1435
1440
// / int i = nondet(int);
1436
1441
// / assume(0 < = i < $VALUES.length);
1437
1442
// / 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 (
1441
1452
code_blockt &assignments,
1442
1453
const exprt &expr,
1443
1454
const java_class_typet &java_class_type,
1444
1455
const source_locationt &location)
1445
1456
{
1446
1457
const irep_idt &class_name = java_class_type.get_name ();
1447
1458
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
+
1452
1468
const symbolt &values = ns.lookup (values_name);
1453
1469
1454
1470
// Access members (length and data) of $VALUES array
@@ -1473,6 +1489,8 @@ void java_object_factoryt::gen_nondet_enum_init(
1473
1489
const dereference_exprt arraycellref (plus);
1474
1490
code_assignt enum_assign (expr, typecast_exprt (arraycellref, expr.type ()));
1475
1491
assignments.add (enum_assign);
1492
+
1493
+ return true ;
1476
1494
}
1477
1495
1478
1496
static void assert_type_consistency (const code_blockt &assignments)
@@ -1510,7 +1528,8 @@ exprt object_factory(
1510
1528
java_object_factory_parameterst parameters,
1511
1529
lifetimet lifetime,
1512
1530
const source_locationt &loc,
1513
- const select_pointer_typet &pointer_type_selector)
1531
+ const select_pointer_typet &pointer_type_selector,
1532
+ message_handlert &log)
1514
1533
{
1515
1534
irep_idt identifier=id2string (goto_functionst::entry_point ())+
1516
1535
" ::" +id2string (base_name);
@@ -1531,10 +1550,7 @@ exprt object_factory(
1531
1550
CHECK_RETURN (!moving_symbol_failed);
1532
1551
1533
1552
java_object_factoryt state (
1534
- loc,
1535
- parameters,
1536
- symbol_table,
1537
- pointer_type_selector);
1553
+ loc, parameters, symbol_table, pointer_type_selector, log );
1538
1554
code_blockt assignments;
1539
1555
state.gen_nondet_init (
1540
1556
assignments,
@@ -1587,6 +1603,7 @@ exprt object_factory(
1587
1603
// / MAY_UPDATE_IN_PLACE: generate a runtime nondet branch between the NO_
1588
1604
// / and MUST_ cases.
1589
1605
// / MUST_UPDATE_IN_PLACE: reinitialize an existing object
1606
+ // / \param log: used to report object construction warnings and failures
1590
1607
// / \return `init_code` gets an instruction sequence to initialize or
1591
1608
// / reinitialize `expr` and child objects it refers to. `symbol_table` is
1592
1609
// / modified with any new symbols created. This includes any necessary
@@ -1600,13 +1617,11 @@ void gen_nondet_init(
1600
1617
lifetimet lifetime,
1601
1618
const java_object_factory_parameterst &object_factory_parameters,
1602
1619
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)
1604
1622
{
1605
1623
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 );
1610
1625
code_blockt assignments;
1611
1626
state.gen_nondet_init (
1612
1627
assignments,
@@ -1634,7 +1649,8 @@ exprt object_factory(
1634
1649
symbol_tablet &symbol_table,
1635
1650
const java_object_factory_parameterst &object_factory_parameters,
1636
1651
lifetimet lifetime,
1637
- const source_locationt &location)
1652
+ const source_locationt &location,
1653
+ message_handlert &log)
1638
1654
{
1639
1655
select_pointer_typet pointer_type_selector;
1640
1656
return object_factory (
@@ -1645,7 +1661,8 @@ exprt object_factory(
1645
1661
object_factory_parameters,
1646
1662
lifetime,
1647
1663
location,
1648
- pointer_type_selector);
1664
+ pointer_type_selector,
1665
+ log );
1649
1666
}
1650
1667
1651
1668
// / Call gen_nondet_init() above with a default (identity) pointer_type_selector
@@ -1657,7 +1674,8 @@ void gen_nondet_init(
1657
1674
bool skip_classid,
1658
1675
lifetimet lifetime,
1659
1676
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)
1661
1679
{
1662
1680
select_pointer_typet pointer_type_selector;
1663
1681
gen_nondet_init (
@@ -1669,7 +1687,8 @@ void gen_nondet_init(
1669
1687
lifetime,
1670
1688
object_factory_parameters,
1671
1689
pointer_type_selector,
1672
- update_in_place);
1690
+ update_in_place,
1691
+ log );
1673
1692
}
1674
1693
1675
1694
// / Adds a call for the given method to the end of `assignments` if the method
0 commit comments