Skip to content

Commit 71abff3

Browse files
committed
Make find_widest_union_component safe for non-constant sizes
This should make it safer to use and enables re-use as part of pointer_offset_bits.
1 parent dd18db5 commit 71abff3

File tree

3 files changed

+16
-21
lines changed

3 files changed

+16
-21
lines changed

src/util/pointer_offset_size.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,16 @@ pointer_offset_bits(const typet &type, const namespacet &ns)
154154
else if(type.id()==ID_union)
155155
{
156156
const union_typet &union_type=to_union_type(type);
157-
mp_integer result=0;
158-
159-
// compute max
160-
161-
for(const auto &c : union_type.components())
162-
{
163-
const typet &subtype = c.type();
164-
auto sub_size = pointer_offset_bits(subtype, ns);
165157

166-
if(!sub_size.has_value())
167-
return {};
158+
if(union_type.components().empty())
159+
return mp_integer{0};
168160

169-
if(*sub_size > result)
170-
result = *sub_size;
171-
}
161+
const auto widest_member = union_type.find_widest_union_component(ns);
172162

173-
return result;
163+
if(widest_member.has_value())
164+
return widest_member->second;
165+
else
166+
return {};
174167
}
175168
else if(type.id()==ID_signedbv ||
176169
type.id()==ID_unsignedbv ||

src/util/std_types.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,25 +294,28 @@ union_typet::find_widest_union_component(const namespacet &ns) const
294294
{
295295
const union_typet::componentst &comps = components();
296296

297-
mp_integer max_width = 0;
297+
optionalt<mp_integer> max_width;
298298
typet max_comp_type;
299299
irep_idt max_comp_name;
300300

301301
for(const auto &comp : comps)
302302
{
303303
auto element_width = pointer_offset_bits(comp.type(), ns);
304304

305-
if(!element_width.has_value() || *element_width <= max_width)
305+
if(!element_width.has_value())
306+
return {};
307+
308+
if(max_width.has_value() && *element_width <= *max_width)
306309
continue;
307310

308311
max_width = *element_width;
309312
max_comp_type = comp.type();
310313
max_comp_name = comp.get_name();
311314
}
312315

313-
if(max_width == 0)
316+
if(!max_width.has_value())
314317
return {};
315318
else
316319
return std::make_pair(
317-
struct_union_typet::componentt{max_comp_name, max_comp_type}, max_width);
320+
struct_union_typet::componentt{max_comp_name, max_comp_type}, *max_width);
318321
}

src/util/std_types.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,8 @@ class union_typet:public struct_union_typet
401401
{
402402
}
403403

404-
/// Determine the member of maximum fixed bit width in a union type. If no
405-
/// member, or no member of fixed and non-zero width can be found, return
406-
/// nullopt.
404+
/// Determine the member of maximum bit width in a union type. If no member,
405+
/// or a member of non-fixed width can be found, return nullopt.
407406
/// \param union_type: Type to determine the member of.
408407
/// \param ns: Namespace to resolve tag types.
409408
/// \return Pair of a componentt pointing to the maximum fixed bit-width

0 commit comments

Comments
 (0)