Skip to content

Commit 05fd4ef

Browse files
committed
Make failed nondet Enum assignment non-fatal
Previously we always expected an Enum type's VALUES array to be present if it may be created in a stub method. However while this is easy for a front-end to ensure when the Enum is a direct return type or member of a stub return type, there are other cases where the object factory can end up building a nondet Enum, such as generic type substitution and usage-inferred stub return types. Until (if ever) ci-lazy-methods can precisely mimic the object factory's behaviour, we're better off tolerating the case where the VALUES array remains missing than killing the entire run.
1 parent d285eb8 commit 05fd4ef

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class java_object_factoryt
104104
update_in_placet,
105105
const source_locationt &location);
106106

107-
void gen_nondet_enum_init(
107+
bool gen_nondet_enum_init(
108108
code_blockt &assignments,
109109
const exprt &expr,
110110
const java_class_typet &java_class_type,
@@ -263,8 +263,8 @@ void java_object_factoryt::gen_pointer_target_init(
263263
}
264264
if(target_class_type.get_base("java::java.lang.Enum"))
265265
{
266-
gen_nondet_enum_init(assignments, expr, target_class_type, location);
267-
return;
266+
if(gen_nondet_enum_init(assignments, expr, target_class_type, location))
267+
return;
268268
}
269269
}
270270

@@ -1460,18 +1460,23 @@ void java_object_factoryt::gen_nondet_array_init(
14601460
/// expr = $VALUES[i];
14611461
/// where $VALUES is a variable generated by the Java compiler that stores
14621462
/// the array that is returned by Enum.values().
1463-
void java_object_factoryt::gen_nondet_enum_init(
1463+
/// This may fail if the $VALUES static field is not present, which gives the
1464+
/// possible values of a particular enum subtype. Ensuring that field is in the
1465+
/// symbol table when this method may be applicable is the driver program's
1466+
/// responsibility: for example, \ref ci_lazy_methods.cpp makes some effort to
1467+
/// retain this field when a stub method might refer to it.
1468+
/// \return true on success
1469+
bool java_object_factoryt::gen_nondet_enum_init(
14641470
code_blockt &assignments,
14651471
const exprt &expr,
14661472
const java_class_typet &java_class_type,
14671473
const source_locationt &location)
14681474
{
14691475
const irep_idt &class_name = java_class_type.get_name();
14701476
const irep_idt values_name = id2string(class_name) + ".$VALUES";
1471-
INVARIANT(
1472-
ns.get_symbol_table().has_symbol(values_name),
1473-
"The $VALUES array (populated by clinit_wrapper) should be in the "
1474-
"symbol table");
1477+
if(!ns.get_symbol_table().has_symbol(values_name))
1478+
return false;
1479+
14751480
const symbolt &values = ns.lookup(values_name);
14761481

14771482
// Access members (length and data) of $VALUES array
@@ -1496,6 +1501,8 @@ void java_object_factoryt::gen_nondet_enum_init(
14961501
const dereference_exprt arraycellref(plus);
14971502
code_assignt enum_assign(expr, typecast_exprt(arraycellref, expr.type()));
14981503
assignments.add(enum_assign);
1504+
1505+
return true;
14991506
}
15001507

15011508
static void assert_type_consistency(const code_blockt &assignments)

0 commit comments

Comments
 (0)