@@ -1205,6 +1205,29 @@ void java_object_factoryt::array_loop_init_code(
1205
1205
plus_exprt (array_init_symexpr, counter_expr, array_init_symexpr.type ()),
1206
1206
array_init_symexpr.type ().subtype ());
1207
1207
1208
+ bool new_item_is_primitive = arraycellref.type ().id () != ID_pointer;
1209
+
1210
+ // Use a temporary to initialise a new, or update an existing, non-primitive.
1211
+ // This makes it clearer that in a sequence like
1212
+ // `new_array_item->x = y; new_array_item->z = w;` that all the
1213
+ // `new_array_item` references must alias, cf. the harder-to-analyse
1214
+ // `some_expr[idx]->x = y; some_expr[idx]->z = w;`
1215
+ exprt init_expr;
1216
+ if (new_item_is_primitive)
1217
+ {
1218
+ init_expr = arraycellref;
1219
+ }
1220
+ else
1221
+ {
1222
+ init_expr = allocate_objects.allocate_automatic_local_object (
1223
+ arraycellref.type (), " new_array_item" );
1224
+
1225
+ // If we're updating an existing array item, read the existing object that
1226
+ // we (may) alter:
1227
+ if (update_in_place != update_in_placet::NO_UPDATE_IN_PLACE)
1228
+ assignments.add (code_assignt (init_expr, arraycellref));
1229
+ }
1230
+
1208
1231
// MUST_UPDATE_IN_PLACE only applies to this object.
1209
1232
// If this is a pointer to another object, offer the chance
1210
1233
// to leave it alone by setting MAY_UPDATE_IN_PLACE instead.
@@ -1214,16 +1237,23 @@ void java_object_factoryt::array_loop_init_code(
1214
1237
update_in_place;
1215
1238
gen_nondet_init (
1216
1239
assignments,
1217
- arraycellref ,
1218
- false , // is_sub
1219
- false , // skip_classid
1240
+ init_expr ,
1241
+ false , // is_sub
1242
+ false , // skip_classid
1220
1243
// These are variable in number, so use dynamic allocator:
1221
1244
lifetimet::DYNAMIC,
1222
1245
element_type, // override
1223
1246
depth,
1224
1247
child_update_in_place,
1225
1248
location);
1226
1249
1250
+ if (!new_item_is_primitive)
1251
+ {
1252
+ // We used a temporary variable to update or initialise an array item;
1253
+ // now write it into the array:
1254
+ assignments.add (code_assignt (arraycellref, init_expr));
1255
+ }
1256
+
1227
1257
exprt java_one=from_integer (1 , java_int_type ());
1228
1258
code_assignt incr (counter_expr, plus_exprt (counter_expr, java_one));
1229
1259
0 commit comments