Skip to content

Commit 1afc3ae

Browse files
authored
Merge pull request #6448 from tautschnig/bit-updates
Byte updates using bit fields require extension to full bytes
2 parents 99c5a92 + eeb1372 commit 1afc3ae

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

regression/cbmc/Promotion3/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33

44
^EXIT=0$

regression/cbmc/havoc_slice/test_struct_b_slice.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
test_struct_b_slice.c
33

44
^EXIT=10$

src/goto-programs/builtin_functions.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected]
2222
#include <util/prefix.h>
2323
#include <util/rational.h>
2424
#include <util/rational_tools.h>
25+
#include <util/simplify_expr.h>
2526
#include <util/symbol_table.h>
2627

2728
#include <langapi/language_util.h>
@@ -699,7 +700,7 @@ void goto_convertt::do_havoc_slice(
699700
t->source_location_nonconst().set_comment(
700701
"assertion havoc_slice " + from_expr(ns, identifier, ok_expr));
701702

702-
const array_typet array_type(char_type(), arguments[1]);
703+
const array_typet array_type(char_type(), simplify_expr(arguments[1], ns));
703704

704705
const symbolt &nondet_contents =
705706
new_tmp_symbol(array_type, "nondet_contents", dest, source_location, mode);

src/solvers/lowering/byte_operators.cpp

+41-2
Original file line numberDiff line numberDiff line change
@@ -2278,20 +2278,59 @@ exprt lower_byte_update(const byte_update_exprt &src, const namespacet &ns)
22782278
// place.
22792279
// 4) Construct a new object.
22802280
optionalt<exprt> non_const_update_bound;
2281-
auto update_size_expr_opt = size_of_expr(src.value().type(), ns);
2281+
// update value, may require extension to full bytes
2282+
exprt update_value = src.value();
2283+
auto update_size_expr_opt = size_of_expr(update_value.type(), ns);
22822284
CHECK_RETURN(update_size_expr_opt.has_value());
22832285
simplify(update_size_expr_opt.value(), ns);
22842286

22852287
if(!update_size_expr_opt.value().is_constant())
22862288
non_const_update_bound = *update_size_expr_opt;
2289+
else
2290+
{
2291+
auto update_bits = pointer_offset_bits(update_value.type(), ns);
2292+
// If the following invariant fails, then the type was only found to be
2293+
// constant via simplification. Such instances should be fixed at the place
2294+
// introducing these constant-but-not-constant_exprt type sizes.
2295+
DATA_INVARIANT(
2296+
update_bits.has_value(), "constant size-of should imply fixed bit width");
2297+
const size_t update_bits_int = numeric_cast_v<size_t>(*update_bits);
2298+
2299+
if(update_bits_int % 8 != 0)
2300+
{
2301+
DATA_INVARIANT(
2302+
can_cast_type<bitvector_typet>(update_value.type()),
2303+
"non-byte aligned type expected to be a bitvector type");
2304+
size_t n_extra_bits = 8 - update_bits_int % 8;
2305+
2306+
endianness_mapt endianness_map(
2307+
src.op().type(), src.id() == ID_byte_update_little_endian, ns);
2308+
const auto bounds = map_bounds(
2309+
endianness_map, update_bits_int, update_bits_int + n_extra_bits - 1);
2310+
extractbits_exprt extra_bits{
2311+
src.op(), bounds.ub, bounds.lb, bv_typet{n_extra_bits}};
2312+
2313+
update_value =
2314+
concatenation_exprt{typecast_exprt::conditional_cast(
2315+
update_value, bv_typet{update_bits_int}),
2316+
extra_bits,
2317+
bitvector_typet{update_value.type().id(),
2318+
update_bits_int + n_extra_bits}};
2319+
}
2320+
else
2321+
{
2322+
update_size_expr_opt =
2323+
from_integer(update_bits_int / 8, update_size_expr_opt->type());
2324+
}
2325+
}
22872326

22882327
const irep_idt extract_opcode = src.id() == ID_byte_update_little_endian
22892328
? ID_byte_extract_little_endian
22902329
: ID_byte_extract_big_endian;
22912330

22922331
const byte_extract_exprt byte_extract_expr{
22932332
extract_opcode,
2294-
src.value(),
2333+
update_value,
22952334
from_integer(0, src.offset().type()),
22962335
array_typet{bv_typet{8}, *update_size_expr_opt}};
22972336

0 commit comments

Comments
 (0)