Skip to content

Commit 62760f9

Browse files
authored
Merge pull request #5251 from tautschnig/factor-out-max-member
Factor out computation of maximum union member
2 parents 0d93d11 + b44360c commit 62760f9

File tree

1 file changed

+47
-40
lines changed

1 file changed

+47
-40
lines changed

src/solvers/lowering/byte_operators.cpp

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,41 @@ 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_type: Type to determine the member of.
28+
/// \param ns: Namespace to resolve tag types.
29+
/// \return Pair of a componentt pointing to the maximum fixed bit-width
30+
/// member of \p union_type and the bit width of that member.
31+
static optionalt<std::pair<struct_union_typet::componentt, mp_integer>>
32+
find_widest_union_component(const union_typet &union_type, const namespacet &ns)
33+
{
34+
const union_typet::componentst &components = union_type.components();
35+
36+
mp_integer max_width = 0;
37+
typet max_comp_type;
38+
irep_idt max_comp_name;
39+
40+
for(const auto &comp : components)
41+
{
42+
auto element_width = pointer_offset_bits(comp.type(), ns);
43+
44+
if(!element_width.has_value() || *element_width <= max_width)
45+
continue;
46+
47+
max_width = *element_width;
48+
max_comp_type = comp.type();
49+
max_comp_name = comp.get_name();
50+
}
51+
52+
if(max_width == 0)
53+
return {};
54+
else
55+
return std::make_pair(
56+
struct_union_typet::componentt{max_comp_name, max_comp_type}, max_width);
57+
}
58+
2459
static exprt bv_to_expr(
2560
const exprt &bitvector_expr,
2661
const typet &target_type,
@@ -1124,31 +1159,18 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
11241159
else if(src.type().id() == ID_union || src.type().id() == ID_union_tag)
11251160
{
11261161
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;
11321162

1133-
for(const auto &comp : components)
1134-
{
1135-
auto element_width = pointer_offset_bits(comp.type(), ns);
1136-
1137-
if(!element_width.has_value() || *element_width <= max_width)
1138-
continue;
1163+
const auto widest_member = find_widest_union_component(union_type, ns);
11391164

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)
1165+
if(widest_member.has_value())
11461166
{
11471167
byte_extract_exprt tmp(unpacked);
1148-
tmp.type() = max_comp_type;
1168+
tmp.type() = widest_member->first.type();
11491169

11501170
return union_exprt(
1151-
max_comp_name, lower_byte_extract(tmp, ns), src.type());
1171+
widest_member->first.get_name(),
1172+
lower_byte_extract(tmp, ns),
1173+
src.type());
11521174
}
11531175
}
11541176

@@ -1945,34 +1967,19 @@ static exprt lower_byte_update_union(
19451967
const optionalt<exprt> &non_const_update_bound,
19461968
const namespacet &ns)
19471969
{
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-
}
1970+
const auto widest_member = find_widest_union_component(union_type, ns);
19651971

19661972
PRECONDITION_WITH_DIAGNOSTICS(
1967-
max_width > 0,
1973+
widest_member.has_value(),
19681974
"lower_byte_update of union of unknown size is not supported");
19691975

19701976
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;
1977+
bu.set_op(member_exprt{
1978+
src.op(), widest_member->first.get_name(), widest_member->first.type()});
1979+
bu.type() = widest_member->first.type();
19731980

19741981
return union_exprt{
1975-
max_comp_name,
1982+
widest_member->first.get_name(),
19761983
lower_byte_update(bu, value_as_byte_array, non_const_update_bound, ns),
19771984
src.type()};
19781985
}

0 commit comments

Comments
 (0)