@@ -146,6 +146,54 @@ static struct_exprt bv_to_struct_expr(
146
146
return struct_exprt{std::move (operands), struct_type};
147
147
}
148
148
149
+ // / Convert a bitvector-typed expression \p bitvector_expr to a union-typed
150
+ // / expression. See \ref bv_to_expr for an overview.
151
+ static union_exprt bv_to_union_expr (
152
+ const exprt &bitvector_expr,
153
+ const union_typet &union_type,
154
+ const endianness_mapt &endianness_map,
155
+ const namespacet &ns)
156
+ {
157
+ const union_typet::componentst &components = union_type.components ();
158
+
159
+ // empty union, handled the same way as done in expr_initializert
160
+ if (components.empty ())
161
+ return union_exprt{irep_idt{}, nil_exprt{}, union_type};
162
+
163
+ const auto max_member_expr =
164
+ find_maximum_union_component (exprt{}, union_type, ns);
165
+
166
+ std::size_t component_bits;
167
+ if (max_member_expr.has_value ())
168
+ component_bits = numeric_cast_v<std::size_t >(max_member_expr->second );
169
+ else
170
+ component_bits = to_bitvector_type (bitvector_expr.type ()).get_width ();
171
+
172
+ if (component_bits == 0 )
173
+ {
174
+ return union_exprt{components.front ().get_name (),
175
+ constant_exprt{irep_idt{}, components.front ().type ()},
176
+ union_type};
177
+ }
178
+
179
+ const auto bounds = map_bounds (endianness_map, 0 , component_bits - 1 );
180
+ bitvector_typet type{bitvector_expr.type ().id (), component_bits};
181
+ const irep_idt &component_name =
182
+ max_member_expr.has_value () ? max_member_expr->first .get_component_name ()
183
+ : components.front ().get_name ();
184
+ const typet &component_type = max_member_expr.has_value ()
185
+ ? max_member_expr->first .type ()
186
+ : components.front ().type ();
187
+ return union_exprt{
188
+ component_name,
189
+ bv_to_expr (
190
+ extractbits_exprt{bitvector_expr, bounds.ub , bounds.lb , std::move (type)},
191
+ component_type,
192
+ endianness_map,
193
+ ns),
194
+ union_type};
195
+ }
196
+
149
197
// / Convert a bitvector-typed expression \p bitvector_expr to an array-typed
150
198
// / expression. See \ref bv_to_expr for an overview.
151
199
static array_exprt bv_to_array_expr (
@@ -334,6 +382,21 @@ static exprt bv_to_expr(
334
382
result.type () = target_type;
335
383
return std::move (result);
336
384
}
385
+ else if (target_type.id () == ID_union)
386
+ {
387
+ return bv_to_union_expr (
388
+ bitvector_expr, to_union_type (target_type), endianness_map, ns);
389
+ }
390
+ else if (target_type.id () == ID_union_tag)
391
+ {
392
+ union_exprt result = bv_to_union_expr (
393
+ bitvector_expr,
394
+ ns.follow_tag (to_union_tag_type (target_type)),
395
+ endianness_map,
396
+ ns);
397
+ result.type () = target_type;
398
+ return std::move (result);
399
+ }
337
400
else if (target_type.id () == ID_array)
338
401
{
339
402
return bv_to_array_expr (
0 commit comments