Skip to content

Commit 764519a

Browse files
authored
Merge pull request #7360 from tautschnig/bugfixes/b-e-zero
Byte-extract lowering: extracting zero-width struct members is fine
2 parents 3a26e73 + a53fa0f commit 764519a

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <assert.h>
2+
#include <string.h>
3+
4+
union _5557197549936569444_union
5+
{
6+
};
7+
8+
struct _5557197549936569444
9+
{
10+
// _case
11+
unsigned char _case;
12+
// cases -- this member makes all the difference
13+
union _5557197549936569444_union cases;
14+
};
15+
16+
struct _3036371764910125196
17+
{
18+
// t
19+
struct _5557197549936569444 t;
20+
// array
21+
unsigned char array[8l];
22+
};
23+
24+
void main(void)
25+
{
26+
struct _3036371764910125196 data = {.t = {._case = 0}, .array = {0}};
27+
unsigned long int index;
28+
if(index < 2)
29+
{
30+
unsigned char array[4] = {0, 0, 0, 0};
31+
unsigned long start = index * 4ul;
32+
unsigned long end = start + 4ul;
33+
34+
memcpy((unsigned char *)&data.array + start, array, end - start);
35+
assert(data.t._case == 0);
36+
}
37+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
10+
memcpy of objects with zero-width fields at a non-constant offset and with a
11+
non-constant copy width must not result in spurious verification failures.
12+
Example constructed from https://github.com/model-checking/kani/issues/1911.

src/util/lower_byte_operators.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,7 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
12861286

12871287
// the next member would be misaligned, abort
12881288
if(
1289-
!component_bits.has_value() || *component_bits == 0 ||
1289+
!component_bits.has_value() ||
12901290
*component_bits % src.get_bits_per_byte() != 0)
12911291
{
12921292
failed = true;
@@ -1992,7 +1992,7 @@ static exprt lower_byte_update_struct(
19921992
else if(!offset_bytes.has_value())
19931993
{
19941994
// The offset to update is not constant; abort the attempt to update
1995-
// indiviual struct members and instead turn the operand-to-be-updated
1995+
// individual struct members and instead turn the operand-to-be-updated
19961996
// into a byte array, which we know how to update even if the offset is
19971997
// non-constant.
19981998
auto src_size_opt = size_of_expr(src.type(), ns);

0 commit comments

Comments
 (0)