Skip to content

Commit c01d2d5

Browse files
committed
Byte-update lowering: fixup invariant for array-comprehension
In case of an array comprehension the number of operands must not be used to sanity check the update offset (any update offset would be valid). This was observed on several device driver benchmarks in SV-COMP. One example (with --unwind 2): ldv-consumption/32_7a_cilled_linux-3.8-rc1-32_7a-drivers--net--wireless--rndis_wlan.ko-ldv_main0_sequence_infinite_withcheck_stateful.cil.out.i
1 parent e366841 commit c01d2d5

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

regression/cbmc/byte_update12/main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <string.h>
2+
3+
struct S
4+
{
5+
int i;
6+
int j;
7+
};
8+
9+
int main()
10+
{
11+
unsigned x;
12+
char A[x];
13+
__CPROVER_assume(x == sizeof(int));
14+
A[0] = 42;
15+
struct S s;
16+
memcpy(&s, A, x);
17+
__CPROVER_assert((s.i & 0xFF) == 42, "lowest byte is 42");
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE broken-smt-backend
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/solvers/lowering/byte_operators.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1822,7 +1822,8 @@ static exprt lower_byte_update_struct(
18221822
{
18231823
offset = from_integer(0, src.offset().type());
18241824
INVARIANT(
1825-
value_as_byte_array.operands().size() > -*offset_bytes,
1825+
value_as_byte_array.id() != ID_array ||
1826+
value_as_byte_array.operands().size() > -*offset_bytes,
18261827
"members past the update should be handled above");
18271828
first = numeric_cast_v<std::size_t>(-*offset_bytes);
18281829
}

0 commit comments

Comments
 (0)