Skip to content

Commit 459ad22

Browse files
committed
Byte-operator lowering: Add support for byte-extracting unions
We already had support for structs, arrays, vectors in place; add unions following the same approach. This is required for some SV-COMP device driver benchmarks, including ldv-linux-3.16-rc1/43_2a_consumption_linux-3.16-rc1.tar.xz-43_2a-drivers--scsi--qla2xxx--tcm_qla2xxx.ko-entry_point.cil.out.i Adding a test also made apparent that we weren't yet handling unbounded byte extracts (out of a bounded object) in flattening.
1 parent bf62883 commit 459ad22

File tree

4 files changed

+26
-11
lines changed

4 files changed

+26
-11
lines changed

regression/cbmc/union14/main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
int main()
2+
{
3+
unsigned x;
4+
__CPROVER_assume(x > 0);
5+
union U {
6+
unsigned A[x];
7+
};
8+
int i, i_before;
9+
i_before = i;
10+
union U u = *((union U *)&i);
11+
i = u.A[0];
12+
__CPROVER_assert(i == i_before, "going through union works");
13+
}

regression/cbmc/union14/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/solvers/flattening/boolbv_byte_extract.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ bvt map_bv(const bv_endianness_mapt &map, const bvt &src)
3838

3939
bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
4040
{
41+
const std::size_t width = boolbv_width(expr.type());
42+
4143
// array logic does not handle byte operators, thus lower when operating on
4244
// unbounded arrays
43-
if(is_unbounded_array(expr.op().type()))
45+
if(is_unbounded_array(expr.op().type()) || is_unbounded_array(expr.type()) || width == 0)
4446
{
4547
return convert_bv(lower_byte_extract(expr, ns));
4648
}
4749

48-
const std::size_t width = boolbv_width(expr.type());
49-
5050
// special treatment for bit-fields and big-endian:
5151
// we need byte granularity
5252
#if 0
@@ -63,9 +63,6 @@ bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
6363
}
6464
#endif
6565

66-
if(width==0)
67-
return conversion_failed(expr);
68-
6966
// see if the byte number is constant and within bounds, else work from the
7067
// root object
7168
const auto op_bytes_opt = pointer_offset_size(expr.op().type(), ns);

src/solvers/flattening/boolbv_union.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@ bvt boolbvt::convert_union(const union_exprt &expr)
1717
{
1818
std::size_t width=boolbv_width(expr.type());
1919

20-
if(width==0)
21-
return conversion_failed(expr);
22-
2320
const bvt &op_bv=convert_bv(expr.op());
2421

2522
INVARIANT(
26-
op_bv.size() <= width,
23+
width == 0 || op_bv.size() <= width,
2724
"operand bitvector width shall not be larger than the width indicated by "
2825
"the union type");
2926

3027
bvt bv;
31-
bv.resize(width);
28+
bv.resize(std::max(width, op_bv.size()));
3229

3330
if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN)
3431
{

0 commit comments

Comments
 (0)