@@ -190,7 +190,8 @@ Function: flatten_byte_update
190
190
191
191
exprt flatten_byte_update (
192
192
const byte_update_exprt &src,
193
- const namespacet &ns)
193
+ const namespacet &ns,
194
+ bool negative_offset)
194
195
{
195
196
assert (src.operands ().size ()==3 );
196
197
@@ -324,7 +325,11 @@ exprt flatten_byte_update(
324
325
if (is_first_cell)
325
326
overwrite_offset=mod_exprt (src.op1 (),sub_size_expr);
326
327
else if (is_last_cell)
327
- overwrite_offset=minus_exprt (stored_value_offset,minus_exprt (cell_offset,src.op1 ()));
328
+ {
329
+ // This is intentionally negated; passing is_last_cell to flatten below
330
+ // leads to it being negated again later.
331
+ overwrite_offset=minus_exprt (minus_exprt (cell_offset,src.op1 ()),stored_value_offset);
332
+ }
328
333
else
329
334
overwrite_offset=zero_offset;
330
335
@@ -333,9 +338,10 @@ exprt flatten_byte_update(
333
338
overwrite_offset,
334
339
new_value);
335
340
336
- // Call recursively, the array is gone!
341
+ // Call recursively, the array is gone!
342
+ // The last parameter indicates that the
337
343
exprt flattened_byte_update_expr=
338
- flatten_byte_update (byte_update_expr, ns);
344
+ flatten_byte_update (byte_update_expr, ns, is_last_cell );
339
345
340
346
with_exprt with_expr (
341
347
result, cell_index, flattened_byte_update_expr);
@@ -386,12 +392,19 @@ exprt flatten_byte_update(
386
392
binary_predicate_exprt offset_ge_zero (offset_times_eight,ID_ge,from_integer (0 ,offset_type));
387
393
388
394
// Shift the mask and value. Note either shift might discard some of the new value's bits.
389
- if_exprt mask_shifted (offset_ge_zero,
390
- shl_exprt (mask,offset_times_eight),
391
- lshr_exprt (mask,unary_minus_exprt (offset_times_eight)));
392
- if_exprt value_shifted (offset_ge_zero,
393
- shl_exprt (value_extended,offset_times_eight),
394
- lshr_exprt (value_extended,unary_minus_exprt (offset_times_eight)));
395
+ exprt mask_shifted;
396
+ exprt value_shifted;
397
+ if (negative_offset)
398
+ {
399
+ // In this case we shift right, to mask out higher addresses
400
+ // rather than left to mask out lower ones as usual.
401
+ mask_shifted=lshr_exprt (mask,offset_times_eight);
402
+ value_shifted=lshr_exprt (value_extended,offset_times_eight);
403
+ }
404
+ else {
405
+ mask_shifted=shl_exprt (mask,offset_times_eight);
406
+ value_shifted=shl_exprt (value_extended,offset_times_eight);
407
+ }
395
408
396
409
// original_bits &= ~mask
397
410
bitand_exprt bitand_expr (src.op0 (), bitnot_exprt (mask_shifted));
0 commit comments