Skip to content

Commit 2f55076

Browse files
committed
Enable extractbits over arbitrary types, fix byte extract omission
Extractbits can safely be applied to any type as it just turns the bit sequence into a bitvector; thus use extractbits directly instead of performing type casts (which are not as generic) first. Fix a missing struct operands push where the operand had been constructed but was never used. Fixes: diffblue#1209
1 parent de40333 commit 2f55076

File tree

4 files changed

+50
-19
lines changed

4 files changed

+50
-19
lines changed

regression/cbmc/union9/main.c

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <stdlib.h>
2+
#include <stdint.h>
3+
4+
typedef union {
5+
struct {
6+
uint8_t x;
7+
uint8_t z;
8+
} b;
9+
} union_t;
10+
11+
typedef struct {
12+
uint32_t magic;
13+
union_t unions[];
14+
} flex;
15+
16+
int flex_init(flex * flex, size_t num)
17+
{
18+
if (num == 0 || num >= 200) {
19+
return -1;
20+
}
21+
flex->unions[num - 1].b.z = 255;
22+
return 0;
23+
}
24+
25+
int main() {
26+
uint8_t num = nondet_size();
27+
flex * pool = (flex *) malloc(sizeof(flex) + num * sizeof(union_t));
28+
int ret = flex_init(pool, num);
29+
if (num > 0 && num < 200) {
30+
__CPROVER_assert(ret == 0, "Accept inside range");
31+
} else {
32+
__CPROVER_assert(ret != 0, "Reject outside range");
33+
}
34+
}
35+

regression/cbmc/union9/test.desc

+8
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_extractbits.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@ bvt boolbvt::convert_extractbits(const extractbits_exprt &expr)
1717
if(width==0)
1818
return conversion_failed(expr);
1919

20-
const irep_idt &type_id=expr.type().id();
21-
22-
if(type_id!=ID_signedbv &&
23-
type_id!=ID_unsignedbv &&
24-
type_id!=ID_c_enum &&
25-
type_id!=ID_c_enum_tag &&
26-
type_id!=ID_bv)
27-
return conversion_failed(expr);
28-
2920
if(expr.operands().size()!=3)
3021
{
3122
error().source_location=expr.find_source_location();

src/solvers/flattening/flatten_byte_operators.cpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ static exprt unpack_rec(
109109
}
110110
else if(type.id()!=ID_empty)
111111
{
112-
// a basic type; we turn that into logical right shift and
113-
// extractbits while considering endianness
112+
// a basic type; we turn that into extractbits while considering
113+
// endianness
114114
mp_integer bits=pointer_offset_bits(type, ns);
115115
if(bits<0)
116116
{
@@ -121,17 +121,12 @@ static exprt unpack_rec(
121121
bits*=8;
122122
}
123123

124-
// cast to generic bit-vector
125-
typecast_exprt src_tc(src, unsignedbv_typet(integer2size_t(bits)));
126-
127124
for(mp_integer i=0; i<bits; i+=8)
128125
{
129-
lshr_exprt right_shift(src_tc, from_integer(i, index_type()));
130-
131126
extractbits_exprt extractbits(
132-
right_shift,
133-
from_integer(7, index_type()),
134-
from_integer(0, index_type()),
127+
src,
128+
from_integer(i+7, index_type()),
129+
from_integer(i, index_type()),
135130
unsignedbv_typet(8));
136131

137132
if(little_endian)
@@ -283,6 +278,8 @@ exprt flatten_byte_extract(
283278
byte_extract_exprt tmp(unpacked);
284279
tmp.type()=comp.type();
285280
tmp.offset()=simplify_expr(new_offset, ns);
281+
282+
s.move_to_operands(tmp);
286283
}
287284

288285
if(!failed)

0 commit comments

Comments
 (0)