Skip to content

Commit fac56f5

Browse files
committed
Unit test of byte operator lowering
1 parent 4606f58 commit fac56f5

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SRC += analyses/ai/ai.cpp \
3131
path_strategies.cpp \
3232
pointer-analysis/value_set.cpp \
3333
solvers/floatbv/float_utils.cpp \
34+
solvers/lowering/byte_operators.cpp \
3435
solvers/miniBDD/miniBDD.cpp \
3536
solvers/refinement/array_pool/array_pool.cpp \
3637
solvers/refinement/string_constraint_generator_valueof/calculate_max_string_length.cpp \
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for byte_extract/byte_update lowering
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
11+
#include <solvers/lowering/expr_lowering.h>
12+
13+
#include <util/arith_tools.h>
14+
#include <util/byte_operators.h>
15+
#include <util/c_types.h>
16+
#include <util/expr_util.h>
17+
#include <util/namespace.h>
18+
#include <util/simplify_expr.h>
19+
#include <util/std_types.h>
20+
#include <util/symbol_table.h>
21+
22+
SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
23+
{
24+
// this test does require a proper architecture to be set so that byte extract
25+
// uses adequate endianness
26+
cmdlinet cmdline;
27+
config.set(cmdline);
28+
29+
const symbol_tablet symbol_table;
30+
const namespacet ns(symbol_table);
31+
32+
GIVEN("A byte_extract over a POD")
33+
{
34+
const exprt deadbeef = from_integer(0xdeadbeef, unsignedbv_typet(32));
35+
const byte_extract_exprt be1(
36+
ID_byte_extract_little_endian,
37+
deadbeef,
38+
from_integer(1, index_type()),
39+
signedbv_typet(8));
40+
41+
THEN("byte_extract lowering yields the expected value")
42+
{
43+
const exprt lower_be1 = lower_byte_extract(be1, ns);
44+
const exprt lower_be1_s = simplify_expr(lower_be1, ns);
45+
46+
REQUIRE(!has_subexpr(lower_be1, ID_byte_extract_little_endian));
47+
REQUIRE(lower_be1.type() == be1.type());
48+
REQUIRE(lower_be1_s == from_integer(0xbe, signedbv_typet(8)));
49+
50+
byte_extract_exprt be2 = be1;
51+
be2.id(ID_byte_extract_big_endian);
52+
const exprt lower_be2 = lower_byte_extract(be2, ns);
53+
const exprt lower_be2_s = simplify_expr(lower_be2, ns);
54+
55+
REQUIRE(!has_subexpr(lower_be2, ID_byte_extract_big_endian));
56+
REQUIRE(lower_be2.type() == be2.type());
57+
REQUIRE(lower_be2_s == from_integer(0xad, signedbv_typet(8)));
58+
}
59+
}
60+
61+
GIVEN("A collection of types")
62+
{
63+
unsignedbv_typet u8(8);
64+
unsignedbv_typet u32(32);
65+
unsignedbv_typet u64(64);
66+
67+
exprt size = from_integer(8, size_type());
68+
69+
std::vector<typet> types = {
70+
struct_typet({ {"comp1", u32}, {"comp2", u64} }),
71+
struct_typet({ {"comp1", u32}, {"compX", c_bit_field_typet(u8, 4)}, {"pad", c_bit_field_typet(u8, 4)}, {"comp2", u8} }),
72+
union_typet({ {"compA", u32}, {"compB", u64} }),
73+
c_enum_typet(unsignedbv_typet(16)),
74+
array_typet(u8, size),
75+
array_typet(u64, size),
76+
unsignedbv_typet(24),
77+
signedbv_typet(128),
78+
ieee_float_spect::single_precision().to_type(),
79+
pointer_typet(u64, 64),
80+
vector_typet(u8, size),
81+
vector_typet(u64, size),
82+
complex_typet(u32)
83+
};
84+
85+
simplify_exprt simp(ns);
86+
87+
THEN("byte_extract lowering yields the expected value")
88+
{
89+
for(const auto &t1 : types)
90+
{
91+
std::ostringstream oss;
92+
for(int i = 0; i < 64; ++i)
93+
oss << integer2binary(i, 8);
94+
const exprt s = simp.bits2expr(oss.str(), t1, true);
95+
REQUIRE(s.is_not_nil());
96+
97+
for(const auto &t2 : types)
98+
{
99+
oss.str("");
100+
for(int i = 2; i < 66; ++i)
101+
oss << integer2binary(i, 8);
102+
const exprt r = simp.bits2expr(oss.str(), t2, true);
103+
REQUIRE(r.is_not_nil());
104+
105+
const byte_extract_exprt be1(
106+
ID_byte_extract_little_endian,
107+
s,
108+
from_integer(2, index_type()),
109+
t2);
110+
111+
const exprt lower_be1 = lower_byte_extract(be1, ns);
112+
const exprt lower_be1_s = simplify_expr(lower_be1, ns);
113+
114+
REQUIRE(!has_subexpr(lower_be1, ID_byte_extract_little_endian));
115+
REQUIRE(lower_be1.type() == be1.type());
116+
REQUIRE(lower_be1 == r);
117+
REQUIRE(lower_be1_s == r);
118+
119+
const byte_extract_exprt be2(
120+
ID_byte_extract_big_endian,
121+
s,
122+
from_integer(2, index_type()),
123+
t2);
124+
125+
const exprt lower_be2 = lower_byte_extract(be2, ns);
126+
const exprt lower_be2_s = simplify_expr(lower_be2, ns);
127+
128+
REQUIRE(!has_subexpr(lower_be2, ID_byte_extract_big_endian));
129+
REQUIRE(lower_be2.type() == be2.type());
130+
REQUIRE(lower_be2 == r);
131+
REQUIRE(lower_be2_s == r);
132+
}
133+
}
134+
}
135+
}
136+
}
137+
138+
SCENARIO("byte_update_lowering", "[core][solvers][lowering][byte_update]")
139+
{
140+
// this test does require a proper architecture to be set so that byte extract
141+
// uses adequate endianness
142+
cmdlinet cmdline;
143+
config.set(cmdline);
144+
145+
const symbol_tablet symbol_table;
146+
const namespacet ns(symbol_table);
147+
148+
GIVEN("A byte_update of a POD")
149+
{
150+
const exprt deadbeef = from_integer(0xdeadbeef, unsignedbv_typet(32));
151+
const byte_update_exprt bu1(
152+
ID_byte_update_little_endian,
153+
deadbeef,
154+
from_integer(1, index_type()),
155+
from_integer(0x42, unsignedbv_typet(8)));
156+
157+
THEN("byte_update lowering yields the expected value")
158+
{
159+
const exprt lower_bu1 = lower_byte_operators(bu1, ns);
160+
const exprt lower_bu1_s = simplify_expr(lower_bu1, ns);
161+
162+
REQUIRE(!has_subexpr(lower_bu1, ID_byte_extract_little_endian));
163+
REQUIRE(!has_subexpr(lower_bu1, ID_byte_update_little_endian));
164+
REQUIRE(lower_bu1.type() == bu1.type());
165+
REQUIRE(lower_bu1_s == from_integer(0xdead42ef, unsignedbv_typet(32)));
166+
167+
#if 0
168+
// this is currently broken, #2058 will fix it
169+
byte_update_exprt bu2 = bu1;
170+
bu2.id(ID_byte_update_big_endian);
171+
const exprt lower_bu2 = lower_byte_operators(bu2, ns);
172+
const exprt lower_bu2_s = simplify_expr(lower_bu2, ns);
173+
174+
REQUIRE(!has_subexpr(lower_bu2, ID_byte_extract_big_endian));
175+
REQUIRE(!has_subexpr(lower_bu2, ID_byte_update_big_endian));
176+
REQUIRE(lower_bu2.type() == bu2.type());
177+
REQUIRE(lower_bu2_s == from_integer(0xde42beef, unsignedbv_typet(32)));
178+
#endif
179+
}
180+
}
181+
182+
GIVEN("A collection of types")
183+
{
184+
unsignedbv_typet u8(8);
185+
unsignedbv_typet u32(32);
186+
unsignedbv_typet u64(64);
187+
188+
exprt size = from_integer(8, size_type());
189+
190+
std::vector<typet> types = {
191+
struct_typet({ {"comp1", u32}, {"comp2", u64} }),
192+
struct_typet({ {"comp1", u32}, {"compX", c_bit_field_typet(u8, 4)}, {"pad", c_bit_field_typet(u8, 4)}, {"comp2", u8} }),
193+
union_typet({ {"compA", u32}, {"compB", u64} }),
194+
c_enum_typet(unsignedbv_typet(16)),
195+
array_typet(u8, size),
196+
array_typet(u64, size),
197+
unsignedbv_typet(24),
198+
signedbv_typet(128),
199+
ieee_float_spect::single_precision().to_type(),
200+
pointer_typet(u64, 64),
201+
vector_typet(u8, size),
202+
vector_typet(u64, size),
203+
complex_typet(u32)
204+
};
205+
206+
simplify_exprt simp(ns);
207+
208+
THEN("byte_update lowering yields the expected value")
209+
{
210+
for(const auto &t1 : types)
211+
{
212+
std::ostringstream oss;
213+
for(int i = 0; i < 64; ++i)
214+
oss << integer2binary(i, 8);
215+
const exprt s = simp.bits2expr(oss.str(), t1, true);
216+
REQUIRE(s.is_not_nil());
217+
218+
for(const auto &t2 : types)
219+
{
220+
oss.str("");
221+
for(int i = 65; i < 128; ++i)
222+
oss << integer2binary(i, 8);
223+
const exprt u = simp.bits2expr(oss.str(), t2, true);
224+
REQUIRE(u.is_not_nil());
225+
226+
const byte_update_exprt bu1(
227+
ID_byte_update_little_endian,
228+
s,
229+
from_integer(2, index_type()),
230+
u);
231+
232+
const exprt lower_bu1 = lower_byte_extract(bu1, ns);
233+
const exprt lower_bu1_s = simplify_expr(lower_bu1, ns);
234+
235+
REQUIRE(!has_subexpr(lower_bu1, ID_byte_update_little_endian));
236+
REQUIRE(!has_subexpr(lower_bu1, ID_byte_extract_little_endian));
237+
REQUIRE(lower_bu1.type() == bu1.type());
238+
REQUIRE(lower_bu1 == u);
239+
REQUIRE(lower_bu1_s == u);
240+
241+
const byte_extract_exprt bu2(
242+
ID_byte_update_big_endian,
243+
s,
244+
from_integer(2, index_type()),
245+
u);
246+
247+
const exprt lower_bu2 = lower_byte_extract(bu2, ns);
248+
const exprt lower_bu2_s = simplify_expr(lower_bu2, ns);
249+
250+
REQUIRE(!has_subexpr(lower_bu2, ID_byte_update_big_endian));
251+
REQUIRE(!has_subexpr(lower_bu2, ID_byte_extract_big_endian));
252+
REQUIRE(lower_bu2.type() == bu2.type());
253+
REQUIRE(lower_bu2 == u);
254+
REQUIRE(lower_bu2_s == u);
255+
}
256+
}
257+
}
258+
}
259+
}

0 commit comments

Comments
 (0)