@@ -4820,6 +4820,61 @@ void smt2_convt::unflatten(
4820
4820
// nop, already a bv
4821
4821
}
4822
4822
}
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
+ }
4823
4878
else if (type.id () == ID_struct || type.id () == ID_struct_tag)
4824
4879
{
4825
4880
if (use_datatypes)
@@ -5605,18 +5660,11 @@ bool smt2_convt::use_array_theory(const exprt &expr)
5605
5660
const typet &type = expr.type ();
5606
5661
PRECONDITION (type.id ()==ID_array);
5607
5662
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
5610
5664
if (expr.id () == ID_with)
5611
5665
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
- }
5618
5666
else
5619
- return true ;
5667
+ return use_datatypes || expr. id () != ID_member ;
5620
5668
}
5621
5669
5622
5670
void smt2_convt::convert_type (const typet &type)
0 commit comments