Skip to content

Commit bd41e25

Browse files
committed
Unit test lower_byte_extract to/from an array of bits
Byte operator lowering made several assumptions about array elements being byte aligned, which may be true for ANSI C, but isn't the case for our C front-end (which supports arrays of single bits), and not true for the overall framework in general.
1 parent df48549 commit bd41e25

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

unit/solvers/lowering/byte_operators.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,88 @@
2424
#include <util/string_constant.h>
2525
#include <util/symbol_table.h>
2626

27+
TEST_CASE("byte extract and bits", "[core][solvers][lowering][byte_extract]")
28+
{
29+
// this test does require a proper architecture to be set so that byte extract
30+
// uses adequate endianness
31+
cmdlinet cmdline;
32+
config.set(cmdline);
33+
34+
const symbol_tablet symbol_table;
35+
const namespacet ns(symbol_table);
36+
37+
const unsignedbv_typet u16{16};
38+
const exprt sixteen_bits = from_integer(0x1234, u16);
39+
const array_typet bit_array_type{bv_typet{1}, from_integer(16, size_type())};
40+
41+
bool little_endian;
42+
GIVEN("Little endian")
43+
{
44+
little_endian = true;
45+
46+
const auto bit_string = expr2bits(sixteen_bits, little_endian, ns);
47+
REQUIRE(bit_string.has_value());
48+
REQUIRE(bit_string->size() == 16);
49+
50+
const auto array_of_bits =
51+
bits2expr(*bit_string, bit_array_type, little_endian, ns);
52+
REQUIRE(array_of_bits.has_value());
53+
54+
const auto bit_string2 = expr2bits(*array_of_bits, little_endian, ns);
55+
REQUIRE(bit_string2.has_value());
56+
REQUIRE(*bit_string == *bit_string2);
57+
58+
const byte_extract_exprt be1{little_endian ? ID_byte_extract_little_endian
59+
: ID_byte_extract_big_endian,
60+
sixteen_bits,
61+
from_integer(0, index_type()),
62+
bit_array_type};
63+
const exprt lower_be1 = lower_byte_extract(be1, ns);
64+
REQUIRE(lower_be1 == *array_of_bits);
65+
66+
const byte_extract_exprt be2{little_endian ? ID_byte_extract_little_endian
67+
: ID_byte_extract_big_endian,
68+
*array_of_bits,
69+
from_integer(0, index_type()),
70+
u16};
71+
const exprt lower_be2 = lower_byte_extract(be2, ns);
72+
REQUIRE(lower_be2 == sixteen_bits);
73+
}
74+
75+
GIVEN("Big endian")
76+
{
77+
little_endian = false;
78+
79+
const auto bit_string = expr2bits(sixteen_bits, little_endian, ns);
80+
REQUIRE(bit_string.has_value());
81+
REQUIRE(bit_string->size() == 16);
82+
83+
const auto array_of_bits =
84+
bits2expr(*bit_string, bit_array_type, little_endian, ns);
85+
REQUIRE(array_of_bits.has_value());
86+
87+
const auto bit_string2 = expr2bits(*array_of_bits, little_endian, ns);
88+
REQUIRE(bit_string2.has_value());
89+
REQUIRE(*bit_string == *bit_string2);
90+
91+
const byte_extract_exprt be1{little_endian ? ID_byte_extract_little_endian
92+
: ID_byte_extract_big_endian,
93+
sixteen_bits,
94+
from_integer(0, index_type()),
95+
bit_array_type};
96+
const exprt lower_be1 = lower_byte_extract(be1, ns);
97+
REQUIRE(lower_be1 == *array_of_bits);
98+
99+
const byte_extract_exprt be2{little_endian ? ID_byte_extract_little_endian
100+
: ID_byte_extract_big_endian,
101+
*array_of_bits,
102+
from_integer(0, index_type()),
103+
u16};
104+
const exprt lower_be2 = lower_byte_extract(be2, ns);
105+
REQUIRE(lower_be2 == sixteen_bits);
106+
}
107+
}
108+
27109
SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
28110
{
29111
// this test does require a proper architecture to be set so that byte extract
@@ -196,6 +278,7 @@ SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
196278
union_typet({{"compA", u32}, {"compB", u64}}),
197279
c_enum_typet(u16),
198280
c_enum_typet(unsignedbv_typet(128)),
281+
array_typet{bv_typet{1}, from_integer(128, size_type())},
199282
array_typet(u8, size),
200283
array_typet(s32, size),
201284
array_typet(u64, size),

0 commit comments

Comments
 (0)