Skip to content

Commit 5a2df0d

Browse files
tautschnigDaniel Kroening
authored and
Daniel Kroening
committed
Fixes to the byte_operator lowering unit test
Let's only test byte extracts within bounds for now (there is ample work to be done to get those right), but make sure there is possible combination for each pair of types. Endianness needs to be taken into account when constructing the expected value. Disable any non-POD tests as they all need more work.
1 parent 7027037 commit 5a2df0d

File tree

1 file changed

+166
-131
lines changed

1 file changed

+166
-131
lines changed

unit/solvers/lowering/byte_operators.cpp

Lines changed: 166 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -65,96 +65,112 @@ SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
6565
GIVEN("A collection of types")
6666
{
6767
unsignedbv_typet u8(8);
68+
signedbv_typet s8(8);
69+
unsignedbv_typet u16(16);
70+
signedbv_typet s16(16);
6871
unsignedbv_typet u32(32);
72+
signedbv_typet s32(32);
6973
unsignedbv_typet u64(64);
74+
signedbv_typet s64(64);
7075

7176
constant_exprt size = from_integer(8, size_type());
7277

7378
std::vector<typet> types = {
74-
struct_typet({{"comp1", u32}, {"comp2", u64}}),
79+
// struct_typet({{"comp1", u16}, {"comp2", u16}}),
80+
// struct_typet({{"comp1", u32}, {"comp2", u64}}),
7581
#if 0
7682
// not currently handled: components not byte aligned
7783
struct_typet({{"comp1", u32},
7884
{"compX", c_bit_field_typet(u8, 4)},
7985
{"pad", c_bit_field_typet(u8, 4)},
8086
{"comp2", u8}}),
8187
#endif
82-
union_typet({{"compA", u32}, {"compB", u64}}),
83-
c_enum_typet(unsignedbv_typet(16)),
84-
array_typet(u8, size),
85-
array_typet(u64, size),
88+
// union_typet({{"compA", u32}, {"compB", u64}}),
89+
// c_enum_typet(u16),
90+
// c_enum_typet(unsignedbv_typet(128)),
91+
// array_typet(u8, size),
92+
// array_typet(s32, size),
93+
// array_typet(u64, size),
8694
unsignedbv_typet(24),
95+
unsignedbv_typet(128),
96+
signedbv_typet(24),
8797
signedbv_typet(128),
88-
ieee_float_spect::single_precision().to_type(),
89-
pointer_typet(u64, 64),
90-
vector_typet(u8, size),
91-
vector_typet(u64, size),
92-
complex_typet(u32)
98+
// ieee_float_spect::single_precision().to_type(),
99+
// pointer_typet(u64, 64),
100+
// vector_typet(u8, size),
101+
// vector_typet(u64, size),
102+
// complex_typet(s16),
103+
// complex_typet(u64)
93104
};
94105

95106
simplify_exprt simp(ns);
96107

97108
THEN("byte_extract lowering yields the expected value")
98109
{
99-
for(const auto &t1 : types)
110+
for(const auto endianness :
111+
{ID_byte_extract_little_endian, ID_byte_extract_big_endian})
100112
{
101-
std::ostringstream oss;
102-
for(int i = 0; i < 64; ++i)
103-
oss << integer2binary(i, 8);
104-
105-
const auto type_bits = pointer_offset_bits(t1, ns);
106-
REQUIRE(type_bits);
107-
const auto type_bits_int = numeric_cast_v<std::size_t>(*type_bits);
108-
REQUIRE(type_bits_int <= oss.str().size());
109-
const exprt s =
110-
simp.bits2expr(oss.str().substr(0, type_bits_int), t1, true);
111-
REQUIRE(s.is_not_nil());
112-
113-
for(const auto &t2 : types)
113+
for(const auto &t1 : types)
114114
{
115-
oss.str("");
116-
for(int i = 2; i < 66; ++i)
117-
oss << integer2binary(i, 8);
118-
119-
const auto type_bits_2 = pointer_offset_bits(t2, ns);
120-
REQUIRE(type_bits_2);
121-
const auto type_bits_2_int =
122-
numeric_cast_v<std::size_t>(*type_bits_2);
123-
REQUIRE(type_bits_2_int <= oss.str().size());
124-
const exprt r =
125-
simp.bits2expr(oss.str().substr(0, type_bits_2_int), t2, true);
126-
REQUIRE(r.is_not_nil());
127-
128-
const byte_extract_exprt be1(
129-
ID_byte_extract_little_endian,
130-
s,
131-
from_integer(2, index_type()),
132-
t2);
133-
134-
const exprt lower_be1 = lower_byte_extract(be1, ns);
135-
const exprt lower_be1_s = simplify_expr(lower_be1, ns);
136-
137-
// TODO: does not currently hold
138-
// REQUIRE(!has_subexpr(lower_be1, ID_byte_extract_little_endian));
139-
REQUIRE(lower_be1.type() == be1.type());
140-
// TODO: does not currently hold
141-
// REQUIRE(lower_be1 == r);
142-
// TODO: does not currently hold
143-
// REQUIRE(lower_be1_s == r);
144-
145-
const byte_extract_exprt be2(
146-
ID_byte_extract_big_endian, s, from_integer(2, index_type()), t2);
147-
148-
const exprt lower_be2 = lower_byte_extract(be2, ns);
149-
const exprt lower_be2_s = simplify_expr(lower_be2, ns);
150-
151-
// TODO: does not currently hold
152-
REQUIRE(!has_subexpr(lower_be2, ID_byte_extract_big_endian));
153-
REQUIRE(lower_be2.type() == be2.type());
154-
// TODO: does not currently hold
155-
// REQUIRE(lower_be2 == r);
156-
// TODO: does not currently hold
157-
// REQUIRE(lower_be2_s == r);
115+
std::ostringstream oss;
116+
for(int i = 0; i < 64; ++i)
117+
{
118+
std::string bits = integer2binary(i, 8);
119+
std::reverse(bits.begin(), bits.end());
120+
oss << bits;
121+
}
122+
123+
const auto type_bits = pointer_offset_bits(t1, ns);
124+
REQUIRE(type_bits);
125+
const auto type_bits_int = numeric_cast_v<std::size_t>(*type_bits);
126+
REQUIRE(type_bits_int <= oss.str().size());
127+
const exprt s = simp.bits2expr(
128+
oss.str().substr(0, type_bits_int),
129+
t1,
130+
endianness == ID_byte_extract_little_endian);
131+
REQUIRE(s.is_not_nil());
132+
133+
for(const auto &t2 : types)
134+
{
135+
oss.str("");
136+
for(int i = 2; i < 64; ++i)
137+
{
138+
std::string bits = integer2binary(i, 8);
139+
std::reverse(bits.begin(), bits.end());
140+
oss << bits;
141+
}
142+
143+
const auto type_bits_2 = pointer_offset_bits(t2, ns);
144+
REQUIRE(type_bits_2);
145+
146+
// for now only extract within bounds
147+
if(*type_bits_2 + 16 > *type_bits)
148+
continue;
149+
150+
const auto type_bits_2_int =
151+
numeric_cast_v<std::size_t>(*type_bits_2);
152+
REQUIRE(type_bits_2_int <= oss.str().size());
153+
const exprt r = simp.bits2expr(
154+
oss.str().substr(0, type_bits_2_int),
155+
t2,
156+
endianness == ID_byte_extract_little_endian);
157+
REQUIRE(r.is_not_nil());
158+
159+
const byte_extract_exprt be(
160+
endianness, s, from_integer(2, index_type()), t2);
161+
162+
const exprt lower_be = lower_byte_extract(be, ns);
163+
const exprt lower_be_s = simplify_expr(lower_be, ns);
164+
165+
// TODO: does not currently hold
166+
// REQUIRE(!has_subexpr(lower_be, ID_byte_extract_little_endian));
167+
// REQUIRE(!has_subexpr(lower_be, ID_byte_extract_big_endian));
168+
REQUIRE(lower_be.type() == be.type());
169+
// TODO: does not currently hold
170+
// REQUIRE(lower_be == r);
171+
// TODO: does not currently hold
172+
// REQUIRE(lower_be_s == r);
173+
}
158174
}
159175
}
160176
}
@@ -208,13 +224,19 @@ SCENARIO("byte_update_lowering", "[core][solvers][lowering][byte_update]")
208224
GIVEN("A collection of types")
209225
{
210226
unsignedbv_typet u8(8);
227+
signedbv_typet s8(8);
228+
unsignedbv_typet u16(16);
229+
signedbv_typet s16(16);
211230
unsignedbv_typet u32(32);
231+
signedbv_typet s32(32);
212232
unsignedbv_typet u64(64);
233+
signedbv_typet s64(64);
213234

214235
constant_exprt size = from_integer(8, size_type());
215236

216237
std::vector<typet> types = {
217238
// TODO: only arrays and scalars
239+
// struct_typet({{"comp1", u16}, {"comp2", u16}}),
218240
// struct_typet({{"comp1", u32}, {"comp2", u64}}),
219241
#if 0
220242
// not currently handled: components not byte aligned
@@ -225,83 +247,96 @@ SCENARIO("byte_update_lowering", "[core][solvers][lowering][byte_update]")
225247
#endif
226248
// TODO: only arrays and scalars
227249
// union_typet({{"compA", u32}, {"compB", u64}}),
228-
// c_enum_typet(unsignedbv_typet(16)),
229-
array_typet(u8, size),
230-
array_typet(u64, size),
250+
// c_enum_typet(u16),
251+
// c_enum_typet(unsignedbv_typet(128)),
252+
// array_typet(u8, size),
253+
// array_typet(s32, size),
254+
// array_typet(u64, size),
231255
unsignedbv_typet(24),
256+
unsignedbv_typet(128),
257+
signedbv_typet(24),
232258
signedbv_typet(128),
233-
ieee_float_spect::single_precision().to_type(),
234-
pointer_typet(u64, 64),
259+
// ieee_float_spect::single_precision().to_type(),
260+
// pointer_typet(u64, 64),
235261
// TODO: only arrays and scalars
236262
// vector_typet(u8, size),
237263
// vector_typet(u64, size),
238-
// complex_typet(u32)
264+
// complex_typet(s16),
265+
// complex_typet(u64)
239266
};
240267

241268
simplify_exprt simp(ns);
242269

243270
THEN("byte_update lowering yields the expected value")
244271
{
245-
for(const auto &t1 : types)
272+
for(const auto endianness :
273+
{ID_byte_update_little_endian, ID_byte_update_big_endian})
246274
{
247-
std::ostringstream oss;
248-
for(int i = 0; i < 64; ++i)
249-
oss << integer2binary(i, 8);
250-
251-
const auto type_bits = pointer_offset_bits(t1, ns);
252-
REQUIRE(type_bits);
253-
const auto type_bits_int = numeric_cast_v<std::size_t>(*type_bits);
254-
REQUIRE(type_bits_int <= oss.str().size());
255-
const exprt s =
256-
simp.bits2expr(oss.str().substr(0, type_bits_int), t1, true);
257-
REQUIRE(s.is_not_nil());
258-
259-
for(const auto &t2 : types)
275+
for(const auto &t1 : types)
260276
{
261-
oss.str("");
262-
for(int i = 64; i < 128; ++i)
263-
oss << integer2binary(i, 8);
264-
265-
const auto type_bits_2 = pointer_offset_bits(t2, ns);
266-
REQUIRE(type_bits_2);
267-
const auto type_bits_2_int =
268-
numeric_cast_v<std::size_t>(*type_bits_2);
269-
REQUIRE(type_bits_2_int <= oss.str().size());
270-
const exprt u =
271-
simp.bits2expr(oss.str().substr(0, type_bits_2_int), t2, true);
272-
REQUIRE(u.is_not_nil());
273-
274-
// TODO: currently required
275-
if(type_bits < type_bits_2)
276-
continue;
277-
278-
const byte_update_exprt bu1(
279-
ID_byte_update_little_endian, s, from_integer(2, index_type()), u);
280-
281-
const exprt lower_bu1 = lower_byte_operators(bu1, ns);
282-
const exprt lower_bu1_s = simplify_expr(lower_bu1, ns);
283-
284-
REQUIRE(!has_subexpr(lower_bu1, ID_byte_update_little_endian));
285-
REQUIRE(!has_subexpr(lower_bu1, ID_byte_extract_little_endian));
286-
REQUIRE(lower_bu1.type() == bu1.type());
287-
// TODO: does not currently hold
288-
// REQUIRE(lower_bu1 == u);
289-
// TODO: does not currently hold
290-
// REQUIRE(lower_bu1_s == u);
291-
292-
const byte_update_exprt bu2(
293-
ID_byte_update_big_endian, s, from_integer(2, index_type()), u);
294-
295-
const exprt lower_bu2 = lower_byte_operators(bu2, ns);
296-
const exprt lower_bu2_s = simplify_expr(lower_bu2, ns);
297-
298-
REQUIRE(!has_subexpr(lower_bu2, ID_byte_update_big_endian));
299-
REQUIRE(!has_subexpr(lower_bu2, ID_byte_extract_big_endian));
300-
REQUIRE(lower_bu2.type() == bu2.type());
301-
// TODO: does not currently hold
302-
// REQUIRE(lower_bu2 == u);
303-
// TODO: does not currently hold
304-
// REQUIRE(lower_bu2_s == u);
277+
std::ostringstream oss;
278+
for(int i = 0; i < 64; ++i)
279+
{
280+
std::string bits = integer2binary(i, 8);
281+
std::reverse(bits.begin(), bits.end());
282+
oss << bits;
283+
}
284+
285+
const auto type_bits = pointer_offset_bits(t1, ns);
286+
REQUIRE(type_bits);
287+
const auto type_bits_int = numeric_cast_v<std::size_t>(*type_bits);
288+
REQUIRE(type_bits_int <= oss.str().size());
289+
const std::string s_string = oss.str().substr(0, type_bits_int);
290+
const exprt s = simp.bits2expr(
291+
s_string, t1, endianness == ID_byte_update_little_endian);
292+
REQUIRE(s.is_not_nil());
293+
294+
for(const auto &t2 : types)
295+
{
296+
oss.str("");
297+
for(int i = 64; i < 128; ++i)
298+
{
299+
std::string bits = integer2binary(i, 8);
300+
std::reverse(bits.begin(), bits.end());
301+
oss << bits;
302+
}
303+
304+
const auto type_bits_2 = pointer_offset_bits(t2, ns);
305+
REQUIRE(type_bits_2);
306+
307+
// for now only update within bounds
308+
if(*type_bits_2 + 16 > *type_bits)
309+
continue;
310+
311+
const auto type_bits_2_int =
312+
numeric_cast_v<std::size_t>(*type_bits_2);
313+
REQUIRE(type_bits_2_int <= oss.str().size());
314+
const std::string u_string = oss.str().substr(0, type_bits_2_int);
315+
const exprt u = simp.bits2expr(
316+
u_string, t2, endianness == ID_byte_update_little_endian);
317+
REQUIRE(u.is_not_nil());
318+
319+
std::string r_string = s_string;
320+
r_string.replace(16, u_string.size(), u_string);
321+
const exprt r = simp.bits2expr(
322+
r_string, t1, endianness == ID_byte_update_little_endian);
323+
REQUIRE(r.is_not_nil());
324+
325+
const byte_update_exprt bu(
326+
endianness, s, from_integer(2, index_type()), u);
327+
328+
const exprt lower_bu = lower_byte_operators(bu, ns);
329+
const exprt lower_bu_s = simplify_expr(lower_bu, ns);
330+
331+
REQUIRE(!has_subexpr(lower_bu, endianness));
332+
REQUIRE(!has_subexpr(lower_bu, ID_byte_extract_big_endian));
333+
REQUIRE(!has_subexpr(lower_bu, ID_byte_extract_little_endian));
334+
REQUIRE(lower_bu.type() == bu.type());
335+
// TODO: does not currently hold
336+
// REQUIRE(lower_bu == r);
337+
// TODO: does not currently hold
338+
// REQUIRE(lower_bu_s == r);
339+
}
305340
}
306341
}
307342
}

0 commit comments

Comments
 (0)