Skip to content

Commit ad2c6ca

Browse files
authored
Merge pull request #6954 from tautschnig/bugfixes/byte-update-odd-bits
Byte update lowering: never create extractbits over unbounded arrays
2 parents 24f883e + c9e923d commit ad2c6ca

File tree

4 files changed

+54
-10
lines changed

4 files changed

+54
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--big-endian
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--little-endian
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

regression/cbmc/byte_update16/main.c

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
int main()
2+
{
3+
unsigned len;
4+
unsigned A[len];
5+
if(len > 1 || len == 0 || sizeof(unsigned) != 4)
6+
return 0;
7+
8+
A[0] = 0xA5FFFFA5U;
9+
__CPROVER_bitvector[1] *bptr = &A[len - 1];
10+
*bptr = 0;
11+
__CPROVER_assert(A[0] == 0xA5FFFF25U || A[0] == 0x25FFFFA5U, "MSB cleared");
12+
}

src/solvers/lowering/byte_operators.cpp

+26-10
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static struct_exprt bv_to_struct_expr(
108108
member_offset_bits,
109109
member_offset_bits + component_bits - 1);
110110
bitvector_typet type = adjust_width(bitvector_expr.type(), component_bits);
111+
PRECONDITION(pointer_offset_bits(bitvector_expr.type(), ns).has_value());
111112
operands.push_back(bv_to_expr(
112113
extractbits_exprt{bitvector_expr, bounds.ub, bounds.lb, std::move(type)},
113114
comp.type(),
@@ -158,6 +159,7 @@ static union_exprt bv_to_union_expr(
158159
const typet &component_type = widest_member.has_value()
159160
? widest_member->first.type()
160161
: components.front().type();
162+
PRECONDITION(pointer_offset_bits(bitvector_expr.type(), ns).has_value());
161163
return union_exprt{
162164
component_name,
163165
bv_to_expr(
@@ -205,6 +207,7 @@ static array_exprt bv_to_array_expr(
205207
endianness_map, i * subtype_bits_int, ((i + 1) * subtype_bits_int) - 1);
206208
bitvector_typet type =
207209
adjust_width(bitvector_expr.type(), subtype_bits_int);
210+
PRECONDITION(pointer_offset_bits(bitvector_expr.type(), ns).has_value());
208211
operands.push_back(bv_to_expr(
209212
extractbits_exprt{
210213
bitvector_expr, bounds.ub, bounds.lb, std::move(type)},
@@ -251,6 +254,7 @@ static vector_exprt bv_to_vector_expr(
251254
endianness_map, i * subtype_bits_int, ((i + 1) * subtype_bits_int) - 1);
252255
bitvector_typet type =
253256
adjust_width(bitvector_expr.type(), subtype_bits_int);
257+
PRECONDITION(pointer_offset_bits(bitvector_expr.type(), ns).has_value());
254258
operands.push_back(bv_to_expr(
255259
extractbits_exprt{
256260
bitvector_expr, bounds.ub, bounds.lb, std::move(type)},
@@ -297,6 +301,7 @@ static complex_exprt bv_to_complex_expr(
297301
const bitvector_typet type =
298302
adjust_width(bitvector_expr.type(), subtype_bits);
299303

304+
PRECONDITION(pointer_offset_bits(bitvector_expr.type(), ns).has_value());
300305
return complex_exprt{
301306
bv_to_expr(
302307
extractbits_exprt{bitvector_expr, bounds_real.ub, bounds_real.lb, type},
@@ -946,6 +951,8 @@ static exprt unpack_rec(
946951
exprt::operandst byte_operands;
947952
for(; bit_offset < last_bit; bit_offset += 8)
948953
{
954+
PRECONDITION(
955+
pointer_offset_bits(src_as_bitvector.type(), ns).has_value());
949956
extractbits_exprt extractbits(
950957
src_as_bitvector,
951958
from_integer(bit_offset + 7, c_index_type()),
@@ -2013,6 +2020,7 @@ static exprt lower_byte_update_struct(
20132020
elements.push_back(updated_element);
20142021
else
20152022
{
2023+
PRECONDITION(pointer_offset_bits(updated_element.type(), ns).has_value());
20162024
elements.push_back(typecast_exprt::conditional_cast(
20172025
extractbits_exprt{updated_element,
20182026
element_bits_int - 1 + (little_endian ? shift : 0),
@@ -2255,6 +2263,7 @@ static exprt lower_byte_update(
22552263
bitor_expr.type(), src.id() == ID_byte_update_little_endian, ns);
22562264
const auto bounds = map_bounds(endianness_map, 0, type_bits - 1);
22572265

2266+
PRECONDITION(pointer_offset_bits(bitor_expr.type(), ns).has_value());
22582267
return simplify_expr(
22592268
typecast_exprt::conditional_cast(
22602269
extractbits_exprt{
@@ -2301,6 +2310,10 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
23012310
CHECK_RETURN(update_size_expr_opt.has_value());
23022311
simplify(update_size_expr_opt.value(), ns);
23032312

2313+
const irep_idt extract_opcode = src.id() == ID_byte_update_little_endian
2314+
? ID_byte_extract_little_endian
2315+
: ID_byte_extract_big_endian;
2316+
23042317
if(!update_size_expr_opt.value().is_constant())
23052318
non_const_update_bound = *update_size_expr_opt;
23062319
else
@@ -2318,14 +2331,21 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
23182331
DATA_INVARIANT(
23192332
can_cast_type<bitvector_typet>(update_value.type()),
23202333
"non-byte aligned type expected to be a bitvector type");
2321-
size_t n_extra_bits = 8 - update_bits_int % 8;
2334+
const byte_extract_exprt overlapping_byte_extract{
2335+
extract_opcode,
2336+
src.op(),
2337+
simplify_expr(
2338+
plus_exprt{
2339+
src.offset(),
2340+
from_integer(update_bits_int / 8, src.offset().type())},
2341+
ns),
2342+
bv_typet{8}};
2343+
const exprt overlapping_byte =
2344+
lower_byte_extract(overlapping_byte_extract, ns);
23222345

2323-
endianness_mapt endianness_map(
2324-
src.op().type(), src.id() == ID_byte_update_little_endian, ns);
2325-
const auto bounds = map_bounds(
2326-
endianness_map, update_bits_int, update_bits_int + n_extra_bits - 1);
2346+
size_t n_extra_bits = 8 - update_bits_int % 8;
23272347
extractbits_exprt extra_bits{
2328-
src.op(), bounds.ub, bounds.lb, bv_typet{n_extra_bits}};
2348+
overlapping_byte, n_extra_bits - 1, 0, bv_typet{n_extra_bits}};
23292349

23302350
update_value = concatenation_exprt{
23312351
typecast_exprt::conditional_cast(
@@ -2340,10 +2360,6 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
23402360
}
23412361
}
23422362

2343-
const irep_idt extract_opcode = src.id() == ID_byte_update_little_endian
2344-
? ID_byte_extract_little_endian
2345-
: ID_byte_extract_big_endian;
2346-
23472363
const byte_extract_exprt byte_extract_expr{
23482364
extract_opcode,
23492365
update_value,

0 commit comments

Comments
 (0)