@@ -714,11 +714,15 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
714
714
// determine an upper bound of the number of bytes we might need
715
715
exprt upper_bound=size_of_expr (src.type (), ns);
716
716
if (upper_bound.is_not_nil ())
717
+ {
717
718
upper_bound = simplify_expr (
718
719
plus_exprt (
719
720
upper_bound,
720
721
typecast_exprt::conditional_cast (src.offset (), upper_bound.type ())),
721
722
ns);
723
+ }
724
+ else if (src.type ().id () == ID_empty)
725
+ upper_bound = from_integer (0 , size_type ());
722
726
723
727
const auto lower_bound_or_nullopt = numeric_cast<mp_integer>(src.offset ());
724
728
const auto upper_bound_or_nullopt = numeric_cast<mp_integer>(upper_bound);
@@ -1570,9 +1574,11 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
1570
1574
src.id () == ID_byte_update_big_endian,
1571
1575
" byte update expression should either be little or big endian" );
1572
1576
1573
- const irep_idt extract_opcode = src.id () == ID_byte_update_little_endian
1574
- ? ID_byte_extract_little_endian
1575
- : ID_byte_extract_big_endian;
1577
+ // An update of a void-typed object or update by a void-typed value is the
1578
+ // source operand (this is questionable, but may arise when dereferencing
1579
+ // invalid pointers).
1580
+ if (src.type ().id () == ID_empty || src.value ().type ().id () == ID_empty)
1581
+ return src.op ();
1576
1582
1577
1583
// byte_update lowering proceeds as follows:
1578
1584
// 1) Determine the size of the update, with the size of the object to be
@@ -1606,6 +1612,10 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
1606
1612
non_const_update_bound = std::move (update_size_expr);
1607
1613
}
1608
1614
1615
+ const irep_idt extract_opcode = src.id () == ID_byte_update_little_endian
1616
+ ? ID_byte_extract_little_endian
1617
+ : ID_byte_extract_big_endian;
1618
+
1609
1619
const byte_extract_exprt byte_extract_expr{
1610
1620
extract_opcode,
1611
1621
src.value (),
0 commit comments