Skip to content

Commit 1c5d2bc

Browse files
author
Joel Allred
committed
Initialize nondet arrays with a single NONDET
Get rid of the initilization loop for nondet arrays, so the size of nondeterministic arrays of primitive types no longer depend on the max unwind value.
1 parent 32e4ac7 commit 1c5d2bc

File tree

1 file changed

+84
-11
lines changed

1 file changed

+84
-11
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ class java_object_factoryt
167167
const exprt &instance_expr,
168168
const irep_idt &method_name);
169169

170+
void array_primitive_init_code(
171+
code_blockt &assignments,
172+
const exprt &init_array_expr,
173+
const exprt &length_expr,
174+
const typet &element_type,
175+
const exprt &max_length_expr,
176+
const source_locationt &location);
177+
170178
void array_loop_init_code(
171179
code_blockt &assignments,
172180
const exprt &init_array_expr,
@@ -1220,7 +1228,57 @@ codet make_allocate_code(const symbol_exprt &lhs, const exprt &size)
12201228
return code_assignt(lhs, alloc);
12211229
}
12221230

1223-
/// Create code to nondeterministically initialise each element of an array in a
1231+
/// Create code to nondeterministically initialize arrays of primitive type.
1232+
/// The code produced is of the form:
1233+
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1234+
/// int (*array_data_init)[max_length_expr];
1235+
/// array_data_init =
1236+
/// ALLOCATE(int [max_length_expr], max_length_expr, false);
1237+
/// *array_data_init = NONDET(int [max_length_expr]);
1238+
// init_array_expr = *array_data_init;
1239+
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1240+
/// \param [out] assignments : Code block to which the initializing assignments
1241+
/// will be appended.
1242+
/// \param init_array_expr : array data
1243+
/// \param length_expr : array length
1244+
/// \param element_type: type of array elements
1245+
/// \param max_length_expr : the (constant) size to which initialise the array
1246+
/// \param location: Source location associated with nondet-initialization.
1247+
void java_object_factoryt::array_primitive_init_code(
1248+
code_blockt &assignments,
1249+
const exprt &init_array_expr,
1250+
const exprt &length_expr,
1251+
const typet &element_type,
1252+
const exprt &max_length_expr,
1253+
const source_locationt &location)
1254+
{
1255+
array_typet array_type(element_type, max_length_expr);
1256+
1257+
// int (*array_data_init)[max_length_expr];
1258+
const symbol_exprt &tmp_finite_array_pointer =
1259+
allocate_objects.allocate_automatic_local_object(
1260+
pointer_type(array_type), "array_data_init");
1261+
1262+
// array_data_init = ALLOCATE(int [max_length_expr], max_length_expr, false);
1263+
assignments.add(
1264+
make_allocate_code(
1265+
tmp_finite_array_pointer,
1266+
max_length_expr));
1267+
1268+
// *array_data_init = NONDET(int [max_length_expr]);
1269+
const exprt nondet_data=side_effect_expr_nondett(array_type, loc);
1270+
const exprt data_pointer_deref=dereference_exprt(
1271+
tmp_finite_array_pointer,
1272+
array_type);
1273+
assignments.add(code_assignt(data_pointer_deref, nondet_data));
1274+
1275+
// init_array_expr = *array_data_init;
1276+
address_of_exprt tmp_nondet_pointer(
1277+
index_exprt(data_pointer_deref, from_integer(0, java_int_type())));
1278+
assignments.add(code_assignt(init_array_expr, tmp_nondet_pointer));
1279+
}
1280+
1281+
/// Create code to nondeterministically initialize each element of an array in a
12241282
/// loop.
12251283
/// The code produced is of the form (supposing an array of type OBJ):
12261284
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1389,16 +1447,31 @@ void java_object_factoryt::gen_nondet_array_init(
13891447
init_array_expr =
13901448
typecast_exprt(init_array_expr, pointer_type(element_type));
13911449

1392-
// Nondeterministically initialise each element of the array
1393-
array_loop_init_code(
1394-
assignments,
1395-
init_array_expr,
1396-
length_expr,
1397-
element_type,
1398-
max_length_expr,
1399-
depth,
1400-
update_in_place,
1401-
location);
1450+
if(element_type.id() == ID_pointer)
1451+
{
1452+
// For arrays of non-primitive types, nondeterministically initialize each
1453+
// element of the array
1454+
array_loop_init_code(
1455+
assignments,
1456+
init_array_expr,
1457+
length_expr,
1458+
element_type,
1459+
max_length_expr,
1460+
depth,
1461+
update_in_place,
1462+
location);
1463+
}
1464+
else
1465+
{
1466+
// Arrays of primitive types can be initialized with a single instruction
1467+
array_primitive_init_code(
1468+
assignments,
1469+
init_array_expr,
1470+
length_expr,
1471+
element_type,
1472+
max_length_expr,
1473+
location);
1474+
}
14021475
}
14031476

14041477
/// We nondet-initialize enums to be equal to one of the constants defined

0 commit comments

Comments
 (0)