@@ -4820,6 +4820,61 @@ void smt2_convt::unflatten(
48204820 // nop, already a bv
48214821 }
48224822 }
4823+ else if (type.id () == ID_array)
4824+ {
4825+ if (use_datatypes)
4826+ {
4827+ PRECONDITION (use_as_const);
4828+
4829+ if (where == wheret::BEGIN)
4830+ out << " (let ((?ufop" << nesting << " " ;
4831+ else
4832+ {
4833+ out << " )) " ;
4834+
4835+ const array_typet &array_type = to_array_type (type);
4836+
4837+ std::size_t subtype_width = boolbv_width (array_type.element_type ());
4838+
4839+ DATA_INVARIANT (
4840+ array_type.size ().is_constant (),
4841+ " cannot unflatten arrays of non-constant size" );
4842+ mp_integer size =
4843+ numeric_cast_v<mp_integer>(to_constant_expr (array_type.size ()));
4844+
4845+ for (mp_integer i = 1 ; i < size; ++i)
4846+ out << " (store " ;
4847+
4848+ out << " ((as const " ;
4849+ convert_type (array_type);
4850+ out << " ) " ;
4851+ // use element at index 0 as default value
4852+ unflatten (wheret::BEGIN, array_type.element_type (), nesting + 1 );
4853+ out << " ((_ extract " << subtype_width - 1 << " "
4854+ << " 0) ?ufop" << nesting << " )" ;
4855+ unflatten (wheret::END, array_type.element_type (), nesting + 1 );
4856+ out << " ) " ;
4857+
4858+ std::size_t offset = subtype_width;
4859+ for (mp_integer i = 1 ; i < size; ++i, offset += subtype_width)
4860+ {
4861+ convert_expr (from_integer (i, array_type.index_type ()));
4862+ out << ' ' ;
4863+ unflatten (wheret::BEGIN, array_type.element_type (), nesting + 1 );
4864+ out << " ((_ extract " << offset + subtype_width - 1 << " " << offset
4865+ << " ) ?ufop" << nesting << " )" ;
4866+ unflatten (wheret::END, array_type.element_type (), nesting + 1 );
4867+ out << " )" ; // store
4868+ }
4869+
4870+ out << " )" ; // let
4871+ }
4872+ }
4873+ else
4874+ {
4875+ // nop, already a bv
4876+ }
4877+ }
48234878 else if (type.id () == ID_struct || type.id () == ID_struct_tag)
48244879 {
48254880 if (use_datatypes)
@@ -5605,18 +5660,11 @@ bool smt2_convt::use_array_theory(const exprt &expr)
56055660 const typet &type = expr.type ();
56065661 PRECONDITION (type.id ()==ID_array);
56075662
5608- // a union is always flattened; else always use array theory when we have
5609- // datatypes
5663+ // arrays inside structs get flattened, unless we have datatypes
56105664 if (expr.id () == ID_with)
56115665 return use_array_theory (to_with_expr (expr).old ());
5612- else if (auto member = expr_try_dynamic_cast<member_exprt>(expr))
5613- {
5614- // arrays inside structs get flattened, unless we have datatypes
5615- return use_datatypes && member->compound ().type ().id () != ID_union &&
5616- member->compound ().type ().id () != ID_union_tag;
5617- }
56185666 else
5619- return true ;
5667+ return use_datatypes || expr. id () != ID_member ;
56205668}
56215669
56225670void smt2_convt::convert_type (const typet &type)
0 commit comments