@@ -122,16 +122,23 @@ static exprt encode(const with_exprt &with, const namespacet &ns)
122
122
return struct_exprt{components, tag_type};
123
123
}
124
124
125
- // / Non-empty structs are flattened into a large bit vector using concatenation
126
- // / to express all the member operands of \p struct_expr. Empty structs are
127
- // / encoded as a zero byte. This has useful properties such as -
125
+ // / Empty structs and unions are encoded as a zero byte. This has useful
126
+ // / properties such as -
128
127
// / * A zero byte is valid SMT, unlike zero length bit vectors.
129
128
// / * Any two zero byte instances are always equal. This property would not
130
129
// / be true of two instances of a non-det byte for instance.
130
+ static exprt empty_encoding ()
131
+ {
132
+ static auto empty_byte = from_integer (0 , bv_typet{8 });
133
+ return empty_byte;
134
+ }
135
+
136
+ // / Structs are flattened into a large bit vector using concatenation to express
137
+ // / all the member operands of \p struct_expr.
131
138
static exprt encode (const struct_exprt &struct_expr)
132
139
{
133
140
if (struct_expr.operands ().empty ())
134
- return from_integer ( 0 , bv_typet{ 8 } );
141
+ return empty_encoding ( );
135
142
if (struct_expr.operands ().size () == 1 )
136
143
return struct_expr.operands ().front ();
137
144
return concatenation_exprt{struct_expr.operands (), struct_expr.type ()};
@@ -221,6 +228,8 @@ exprt struct_encodingt::encode(exprt expr) const
221
228
update = ::encode (*struct_expr);
222
229
if (const auto union_expr = expr_try_dynamic_cast<union_exprt>(current))
223
230
update = ::encode (*union_expr, *boolbv_width);
231
+ if (can_cast_expr<empty_union_exprt>(current))
232
+ update = ::empty_encoding ();
224
233
if (const auto member_expr = expr_try_dynamic_cast<member_exprt>(current))
225
234
update = encode_member (*member_expr);
226
235
if (update)
0 commit comments