Skip to content

Commit ddfaa65

Browse files
committed
Byte-operator lowering: support void-typed updates
These may be generated when dereferencing invalid pointers, and are just no-ops. Make sure we don't fail as size_of_expr would return nil_exprt() for those.
1 parent 6d5d6cf commit ddfaa65

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

regression/cbmc/Pointer_byte_extract9/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.c
33

44
^EXIT=10$

regression/cbmc/byte_update3/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.c
33
--little-endian
44
^EXIT=0$

regression/cbmc/byte_update5/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.c
33
--little-endian
44
^EXIT=0$

src/solvers/lowering/byte_operators.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,11 +714,15 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
714714
// determine an upper bound of the number of bytes we might need
715715
exprt upper_bound=size_of_expr(src.type(), ns);
716716
if(upper_bound.is_not_nil())
717+
{
717718
upper_bound = simplify_expr(
718719
plus_exprt(
719720
upper_bound,
720721
typecast_exprt::conditional_cast(src.offset(), upper_bound.type())),
721722
ns);
723+
}
724+
else if(src.type().id() == ID_empty)
725+
upper_bound = from_integer(0, size_type());
722726

723727
const auto lower_bound_or_nullopt = numeric_cast<mp_integer>(src.offset());
724728
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)
15701574
src.id() == ID_byte_update_big_endian,
15711575
"byte update expression should either be little or big endian");
15721576

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();
15761582

15771583
// byte_update lowering proceeds as follows:
15781584
// 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)
16061612
non_const_update_bound = std::move(update_size_expr);
16071613
}
16081614

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+
16091619
const byte_extract_exprt byte_extract_expr{
16101620
extract_opcode,
16111621
src.value(),

0 commit comments

Comments
 (0)