Skip to content

Commit a4812d6

Browse files
committed
Factor out computation of maximum union member
Avoids duplicate code and enables future re-use.
1 parent 0d93d11 commit a4812d6

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

src/solvers/lowering/byte_operators.cpp

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,46 @@ Author: Daniel Kroening, [email protected]
2121
#include <util/simplify_expr.h>
2222
#include <util/string_constant.h>
2323

24+
/// Determine the member of maximum fixed bit width in a union type. If no
25+
/// member, or no member of fixed and non-zero width can be found, return
26+
/// nullopt.
27+
/// \param union_expr: Expression to use as compound operand in the resulting
28+
/// member_exprt.
29+
/// \param union_type: Type to determine the member of.
30+
/// \param ns: Namespace to resolve tag types.
31+
/// \return Pair of a member_exprt pointing to the maximum fixed bit-width
32+
/// member of \p union_type and the bit width of that member.
33+
static optionalt<std::pair<member_exprt, mp_integer>>
34+
find_maximum_union_component(
35+
const exprt &union_expr,
36+
const union_typet &union_type,
37+
const namespacet &ns)
38+
{
39+
const union_typet::componentst &components = union_type.components();
40+
41+
mp_integer max_width = 0;
42+
typet max_comp_type;
43+
irep_idt max_comp_name;
44+
45+
for(const auto &comp : components)
46+
{
47+
auto element_width = pointer_offset_bits(comp.type(), ns);
48+
49+
if(!element_width.has_value() || *element_width <= max_width)
50+
continue;
51+
52+
max_width = *element_width;
53+
max_comp_type = comp.type();
54+
max_comp_name = comp.get_name();
55+
}
56+
57+
if(max_width == 0)
58+
return {};
59+
else
60+
return std::make_pair(
61+
member_exprt{union_expr, max_comp_name, max_comp_type}, max_width);
62+
}
63+
2464
static exprt bv_to_expr(
2565
const exprt &bitvector_expr,
2666
const typet &target_type,
@@ -1124,31 +1164,19 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
11241164
else if(src.type().id() == ID_union || src.type().id() == ID_union_tag)
11251165
{
11261166
const union_typet &union_type = to_union_type(ns.follow(src.type()));
1127-
const union_typet::componentst &components = union_type.components();
1128-
1129-
mp_integer max_width = 0;
1130-
typet max_comp_type;
1131-
irep_idt max_comp_name;
1132-
1133-
for(const auto &comp : components)
1134-
{
1135-
auto element_width = pointer_offset_bits(comp.type(), ns);
11361167

1137-
if(!element_width.has_value() || *element_width <= max_width)
1138-
continue;
1168+
const auto max_member_expr =
1169+
find_maximum_union_component(src, union_type, ns);
11391170

1140-
max_width = *element_width;
1141-
max_comp_type = comp.type();
1142-
max_comp_name = comp.get_name();
1143-
}
1144-
1145-
if(max_width > 0)
1171+
if(max_member_expr.has_value())
11461172
{
11471173
byte_extract_exprt tmp(unpacked);
1148-
tmp.type() = max_comp_type;
1174+
tmp.type() = max_member_expr->first.type();
11491175

11501176
return union_exprt(
1151-
max_comp_name, lower_byte_extract(tmp, ns), src.type());
1177+
max_member_expr->first.get_component_name(),
1178+
lower_byte_extract(tmp, ns),
1179+
src.type());
11521180
}
11531181
}
11541182

@@ -1945,34 +1973,19 @@ static exprt lower_byte_update_union(
19451973
const optionalt<exprt> &non_const_update_bound,
19461974
const namespacet &ns)
19471975
{
1948-
const union_typet::componentst &components = union_type.components();
1949-
1950-
mp_integer max_width = 0;
1951-
typet max_comp_type;
1952-
irep_idt max_comp_name;
1953-
1954-
for(const auto &comp : components)
1955-
{
1956-
auto element_width = pointer_offset_bits(comp.type(), ns);
1957-
1958-
if(!element_width.has_value() || *element_width <= max_width)
1959-
continue;
1960-
1961-
max_width = *element_width;
1962-
max_comp_type = comp.type();
1963-
max_comp_name = comp.get_name();
1964-
}
1976+
const auto max_member_expr =
1977+
find_maximum_union_component(src.op(), union_type, ns);
19651978

19661979
PRECONDITION_WITH_DIAGNOSTICS(
1967-
max_width > 0,
1980+
max_member_expr.has_value(),
19681981
"lower_byte_update of union of unknown size is not supported");
19691982

19701983
byte_update_exprt bu = src;
1971-
bu.set_op(member_exprt{src.op(), max_comp_name, max_comp_type});
1972-
bu.type() = max_comp_type;
1984+
bu.set_op(max_member_expr->first);
1985+
bu.type() = max_member_expr->first.type();
19731986

19741987
return union_exprt{
1975-
max_comp_name,
1988+
max_member_expr->first.get_component_name(),
19761989
lower_byte_update(bu, value_as_byte_array, non_const_update_bound, ns),
19771990
src.type()};
19781991
}

0 commit comments

Comments
 (0)