Skip to content

Commit 65cd7eb

Browse files
authored
Merge pull request #6485 from tautschnig/bv_typet-endianness
bv_typet is also sensitive to endianness
2 parents 0d62ff5 + 5bf69a3 commit 65cd7eb

File tree

3 files changed

+79
-24
lines changed

3 files changed

+79
-24
lines changed

src/solvers/lowering/byte_operators.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ static boundst map_bounds(
5050

5151
// big-endian bounds need swapping
5252
if(result.ub < result.lb)
53-
{
54-
result.lb = endianness_map.number_of_bits() - result.lb - 1;
55-
result.ub = endianness_map.number_of_bits() - result.ub - 1;
56-
}
53+
std::swap(result.lb, result.ub);
5754
}
5855

5956
return result;
@@ -1295,7 +1292,7 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
12951292
concatenation_exprt concatenation(
12961293
std::move(op), bitvector_typet(subtype->id(), width_bytes * 8));
12971294

1298-
endianness_mapt map(src.type(), little_endian, ns);
1295+
endianness_mapt map(concatenation.type(), little_endian, ns);
12991296
return bv_to_expr(concatenation, src.type(), map, ns);
13001297
}
13011298
}
@@ -2226,22 +2223,16 @@ static exprt lower_byte_update(
22262223
// original_bits |= newvalue
22272224
bitor_exprt bitor_expr{bitand_expr, value_shifted};
22282225

2229-
if(!is_little_endian && bit_width > type_bits)
2230-
{
2231-
return simplify_expr(
2232-
typecast_exprt::conditional_cast(
2233-
extractbits_exprt{bitor_expr,
2234-
bit_width - 1,
2235-
bit_width - type_bits,
2236-
bv_typet{type_bits}},
2237-
src.type()),
2238-
ns);
2239-
}
2240-
else if(bit_width > type_bits)
2226+
if(bit_width > type_bits)
22412227
{
2228+
endianness_mapt endianness_map(
2229+
bitor_expr.type(), src.id() == ID_byte_update_little_endian, ns);
2230+
const auto bounds = map_bounds(endianness_map, 0, type_bits - 1);
2231+
22422232
return simplify_expr(
22432233
typecast_exprt::conditional_cast(
2244-
extractbits_exprt{bitor_expr, type_bits - 1, 0, bv_typet{type_bits}},
2234+
extractbits_exprt{
2235+
bitor_expr, bounds.ub, bounds.lb, bv_typet{type_bits}},
22452236
src.type()),
22462237
ns);
22472238
}

src/util/endianness_map.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,10 @@ void endianness_mapt::build_big_endian(const typet &src)
5353
{
5454
if(src.id() == ID_c_enum_tag)
5555
build_big_endian(ns.follow_tag(to_c_enum_tag_type(src)));
56-
else if(src.id()==ID_unsignedbv ||
57-
src.id()==ID_signedbv ||
58-
src.id()==ID_fixedbv ||
59-
src.id()==ID_floatbv ||
60-
src.id()==ID_c_enum ||
61-
src.id()==ID_c_bit_field)
56+
else if(
57+
src.id() == ID_unsignedbv || src.id() == ID_signedbv ||
58+
src.id() == ID_fixedbv || src.id() == ID_floatbv || src.id() == ID_c_enum ||
59+
src.id() == ID_c_bit_field || src.id() == ID_bv)
6260
{
6361
// these do get re-ordered!
6462
auto bits = pointer_offset_bits(src, ns); // error is -1

unit/solvers/lowering/byte_operators.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,72 @@
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+
67+
GIVEN("Big endian")
68+
{
69+
little_endian = false;
70+
71+
const auto bit_string = expr2bits(sixteen_bits, little_endian, ns);
72+
REQUIRE(bit_string.has_value());
73+
REQUIRE(bit_string->size() == 16);
74+
75+
const auto array_of_bits =
76+
bits2expr(*bit_string, bit_array_type, little_endian, ns);
77+
REQUIRE(array_of_bits.has_value());
78+
79+
const auto bit_string2 = expr2bits(*array_of_bits, little_endian, ns);
80+
REQUIRE(bit_string2.has_value());
81+
REQUIRE(*bit_string == *bit_string2);
82+
83+
const byte_extract_exprt be1{little_endian ? ID_byte_extract_little_endian
84+
: ID_byte_extract_big_endian,
85+
sixteen_bits,
86+
from_integer(0, index_type()),
87+
bit_array_type};
88+
const exprt lower_be1 = lower_byte_extract(be1, ns);
89+
REQUIRE(lower_be1 == *array_of_bits);
90+
}
91+
}
92+
2793
SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
2894
{
2995
// this test does require a proper architecture to be set so that byte extract

0 commit comments

Comments
 (0)