Skip to content

Commit ddc5539

Browse files
committed
Fix unpack_array_vector to produce an array of bytes
We wrongly created a return type (though not the underlying expression, which was correct!) as an array of elements of the original subtype, even though the sole purpose of unpack_array_vector is to turn the original subtype into a sequence of bytes. We seemingly neither had a test covering this code nor did we have additional result verification in place. Both are now rectified: a new regression test is added, and an invariant is checked right after returning from unpack_rec (which may invoke unpack_array_vector). Fixes: #5718
1 parent 7d6cb94 commit ddc5539

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <stdlib.h>
2+
#include <string.h>
3+
4+
int __VERIFIER_nondet_int();
5+
6+
void main()
7+
{
8+
size_t size;
9+
__CPROVER_assume(size >= 2);
10+
// limit the size to ensure size * sizeof(int) wouldn't overflow, and we don't
11+
// reach the maximum object size
12+
__CPROVER_assume(size <= 1000);
13+
14+
int *dest_buffer = malloc(size * sizeof(int));
15+
int *src_buffer = malloc(size * sizeof(int));
16+
src_buffer[0] = 42;
17+
src_buffer[1] = __VERIFIER_nondet_int();
18+
19+
memcpy(dest_buffer, src_buffer, size * sizeof(int));
20+
__CPROVER_assert(dest_buffer[0] == 42, "should pass");
21+
__CPROVER_assert(dest_buffer[1] == 42, "should fail");
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
4+
^\[main.assertion.1\] line 20 should pass: SUCCESS$
5+
^\[main.assertion.2\] line 21 should fail: FAILURE$
6+
^\*\* 1 of \d+ failed
7+
^VERIFICATION FAILED$
8+
^EXIT=10$
9+
^SIGNAL=0$
10+
--
11+
^warning: ignoring

src/solvers/lowering/byte_operators.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,23 +476,21 @@ static exprt unpack_array_vector(
476476
}
477477

478478
optionalt<exprt> array_vector_size;
479-
optionalt<typet> subtype;
480479
if(src.type().id() == ID_vector)
481480
{
482481
array_vector_size = to_vector_type(src.type()).size();
483-
subtype = to_vector_type(src.type()).subtype();
484482
}
485483
else
486484
{
487485
array_vector_size = to_array_type(src.type()).size();
488-
subtype = to_array_type(src.type()).subtype();
489486
}
490487

488+
491489
return array_comprehension_exprt{
492490
std::move(array_comprehension_index),
493491
std::move(body),
494492
array_typet{
495-
*subtype,
493+
bv_typet{8},
496494
mult_exprt{*array_vector_size,
497495
from_integer(el_bytes, array_vector_size->type())}}};
498496
}
@@ -1034,6 +1032,9 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
10341032
byte_extract_exprt unpacked(src);
10351033
unpacked.op() = unpack_rec(
10361034
src.op(), little_endian, lower_bound_int_opt, upper_bound_int_opt, ns);
1035+
CHECK_RETURN(
1036+
to_bitvector_type(to_type_with_subtype(unpacked.op().type()).subtype())
1037+
.get_width() == 8);
10371038

10381039
if(src.type().id()==ID_array)
10391040
{

0 commit comments

Comments
 (0)