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