Skip to content

Commit 51da7e6

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 ceeb07c commit 51da7e6

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 17 additions & 10 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

@@ -1435,20 +1435,25 @@ void java_object_factoryt::gen_nondet_array_init(
14351435
/// int i = nondet(int);
14361436
/// assume(0 < = i < $VALUES.length);
14371437
/// 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(
1438+
/// where $VALUES is a variable generated by the Java compiler and which gives
1439+
/// the possible values of a particular enum subtype (this is the same array
1440+
/// that is returned by Enum.values()).
1441+
/// This may fail if the $VALUES static field is not present. Ensuring that
1442+
/// field is in the symbol table when this method may be applicable is the
1443+
/// driver program's responsibility: for example, \ref ci_lazy_methods.cpp makes
1444+
/// some effort to retain this field when a stub method might refer to it.
1445+
/// \return true on success
1446+
bool java_object_factoryt::gen_nondet_enum_init(
14411447
code_blockt &assignments,
14421448
const exprt &expr,
14431449
const java_class_typet &java_class_type,
14441450
const source_locationt &location)
14451451
{
14461452
const irep_idt &class_name = java_class_type.get_name();
14471453
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");
1454+
if(!ns.get_symbol_table().has_symbol(values_name))
1455+
return false;
1456+
14521457
const symbolt &values = ns.lookup(values_name);
14531458

14541459
// Access members (length and data) of $VALUES array
@@ -1473,6 +1478,8 @@ void java_object_factoryt::gen_nondet_enum_init(
14731478
const dereference_exprt arraycellref(plus);
14741479
code_assignt enum_assign(expr, typecast_exprt(arraycellref, expr.type()));
14751480
assignments.add(enum_assign);
1481+
1482+
return true;
14761483
}
14771484

14781485
static void assert_type_consistency(const code_blockt &assignments)

0 commit comments

Comments
 (0)