Skip to content

Commit 7632d02

Browse files
authored
Merge pull request #4187 from tautschnig/byte-op-union
byte_extract lowering of unions [blocks: #2068]
2 parents e654aa7 + 761ad8a commit 7632d02

File tree

8 files changed

+65
-7
lines changed

8 files changed

+65
-7
lines changed

regression/cbmc/equality_through_union1/test.desc

Lines changed: 1 addition & 1 deletion
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/equality_through_union2/test.desc

Lines changed: 1 addition & 1 deletion
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/equality_through_union3/test.desc

Lines changed: 1 addition & 1 deletion
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/trace_address_arithmetic1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
--trace
44
^EXIT=10$

regression/cbmc/union11/union_list.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
union_list.c
33

44
^EXIT=0$

regression/cbmc/union8/test.desc

Lines changed: 1 addition & 1 deletion
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$

src/solvers/lowering/byte_operators.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,34 @@ static exprt unpack_rec(
236236
std::move(byte_operands),
237237
array_typet(unsignedbv_typet(8), from_integer(size, size_type())));
238238
}
239+
else if(src.type().id() == ID_union || src.type().id() == ID_union_tag)
240+
{
241+
const union_typet &union_type = to_union_type(ns.follow(src.type()));
242+
const union_typet::componentst &components = union_type.components();
243+
244+
mp_integer max_width = 0;
245+
typet max_comp_type;
246+
irep_idt max_comp_name;
247+
248+
for(const auto &comp : components)
249+
{
250+
auto element_width = pointer_offset_bits(comp.type(), ns);
251+
252+
if(!element_width.has_value() || *element_width <= max_width)
253+
continue;
254+
255+
max_width = *element_width;
256+
max_comp_type = comp.type();
257+
max_comp_name = comp.get_name();
258+
}
259+
260+
if(max_width > 0)
261+
{
262+
member_exprt member(src, max_comp_name, max_comp_type);
263+
return unpack_rec(
264+
member, little_endian, offset_bytes, max_bytes, ns, true);
265+
}
266+
}
239267
else if(src.type().id()!=ID_empty)
240268
{
241269
// a basic type; we turn that into extractbits while considering
@@ -455,6 +483,36 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
455483
if(!failed)
456484
return simplify_expr(s, ns);
457485
}
486+
else if(src.type().id() == ID_union || src.type().id() == ID_union_tag)
487+
{
488+
const union_typet &union_type = to_union_type(ns.follow(src.type()));
489+
const union_typet::componentst &components = union_type.components();
490+
491+
mp_integer max_width = 0;
492+
typet max_comp_type;
493+
irep_idt max_comp_name;
494+
495+
for(const auto &comp : components)
496+
{
497+
auto element_width = pointer_offset_bits(comp.type(), ns);
498+
499+
if(!element_width.has_value() || *element_width <= max_width)
500+
continue;
501+
502+
max_width = *element_width;
503+
max_comp_type = comp.type();
504+
max_comp_name = comp.get_name();
505+
}
506+
507+
if(max_width > 0)
508+
{
509+
byte_extract_exprt tmp(unpacked);
510+
tmp.type() = max_comp_type;
511+
512+
return union_exprt(
513+
max_comp_name, lower_byte_extract(tmp, ns), union_type);
514+
}
515+
}
458516

459517
const exprt &root=unpacked.op();
460518
const exprt &offset=unpacked.offset();

unit/solvers/lowering/byte_operators.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
113113
{"pad", c_bit_field_typet(u8, 4)},
114114
{"comp2", u8}}),
115115
#endif
116-
// union_typet({{"compA", u32}, {"compB", u64}}),
116+
union_typet({{"compA", u32}, {"compB", u64}}),
117117
c_enum_typet(u16),
118118
c_enum_typet(unsignedbv_typet(128)),
119119
array_typet(u8, size),

0 commit comments

Comments
 (0)