@@ -1407,9 +1407,35 @@ void smt2_convt::convert_expr(const exprt &expr)
14071407 out << " (ite " ;
14081408 convert_expr (if_expr.cond ());
14091409 out << " " ;
1410- convert_expr (if_expr.true_case ());
1410+ if (
1411+ expr.type ().id () == ID_array && !use_array_theory (if_expr.true_case ()) &&
1412+ use_array_theory (if_expr.false_case ()))
1413+ {
1414+ unflatten (wheret::BEGIN, expr.type ());
1415+
1416+ convert_expr (if_expr.true_case ());
1417+
1418+ unflatten (wheret::END, expr.type ());
1419+ }
1420+ else
1421+ {
1422+ convert_expr (if_expr.true_case ());
1423+ }
14111424 out << " " ;
1412- convert_expr (if_expr.false_case ());
1425+ if (
1426+ expr.type ().id () == ID_array && use_array_theory (if_expr.true_case ()) &&
1427+ !use_array_theory (if_expr.false_case ()))
1428+ {
1429+ unflatten (wheret::BEGIN, expr.type ());
1430+
1431+ convert_expr (if_expr.false_case ());
1432+
1433+ unflatten (wheret::END, expr.type ());
1434+ }
1435+ else
1436+ {
1437+ convert_expr (if_expr.false_case ());
1438+ }
14131439 out << " )" ;
14141440 }
14151441 else if (expr.id ()==ID_and ||
@@ -4400,50 +4426,63 @@ void smt2_convt::convert_with(const with_exprt &expr)
44004426 }
44014427 else
44024428 {
4429+ auto convert_operand = [this ](const exprt &op)
4430+ {
4431+ // may need to flatten array-theory arrays in there
4432+ if (op.type ().id () == ID_array && use_array_theory (op))
4433+ flatten_array (op);
4434+ else if (op.type ().id () == ID_bool)
4435+ flatten2bv (op);
4436+ else
4437+ convert_expr (op);
4438+ };
4439+
44034440 std::size_t struct_width=boolbv_width (struct_type);
44044441
44054442 // figure out the offset and width of the member
44064443 const boolbv_widtht::membert &m =
44074444 boolbv_width.get_member (struct_type, component_name);
44084445
4409- out << " (let ((?withop " ;
4410- convert_expr (expr.old ());
4411- out << " )) " ;
4412-
44134446 if (m.width ==struct_width)
44144447 {
4415- // the struct is the same as the member, no concat needed,
4416- // ?withop won't be used
4417- convert_expr (value);
4418- }
4419- else if (m.offset ==0 )
4420- {
4421- // the member is at the beginning
4422- out << " (concat "
4423- << " ((_ extract " << (struct_width-1 ) << " "
4424- << m.width << " ) ?withop) " ;
4425- convert_expr (value);
4426- out << " )" ; // concat
4427- }
4428- else if (m.offset +m.width ==struct_width)
4429- {
4430- // the member is at the end
4431- out << " (concat " ;
4432- convert_expr (value);
4433- out << " ((_ extract " << (m.offset - 1 ) << " 0) ?withop))" ;
4448+ // the struct is the same as the member, no concat needed
4449+ convert_operand (value);
44344450 }
44354451 else
44364452 {
4437- // most general case, need two concat-s
4438- out << " (concat (concat "
4439- << " ((_ extract " << (struct_width-1 ) << " "
4440- << (m.offset +m.width ) << " ) ?withop) " ;
4441- convert_expr (value);
4442- out << " ) ((_ extract " << (m.offset -1 ) << " 0) ?withop)" ;
4443- out << " )" ; // concat
4444- }
4453+ out << " (let ((?withop " ;
4454+ convert_operand (expr.old ());
4455+ out << " )) " ;
44454456
4446- out << " )" ; // let ?withop
4457+ if (m.offset == 0 )
4458+ {
4459+ // the member is at the beginning
4460+ out << " (concat "
4461+ << " ((_ extract " << (struct_width - 1 ) << " " << m.width
4462+ << " ) ?withop) " ;
4463+ convert_operand (value);
4464+ out << " )" ; // concat
4465+ }
4466+ else if (m.offset + m.width == struct_width)
4467+ {
4468+ // the member is at the end
4469+ out << " (concat " ;
4470+ convert_operand (value);
4471+ out << " ((_ extract " << (m.offset - 1 ) << " 0) ?withop))" ;
4472+ }
4473+ else
4474+ {
4475+ // most general case, need two concat-s
4476+ out << " (concat (concat "
4477+ << " ((_ extract " << (struct_width - 1 ) << " "
4478+ << (m.offset + m.width ) << " ) ?withop) " ;
4479+ convert_operand (value);
4480+ out << " ) ((_ extract " << (m.offset - 1 ) << " 0) ?withop)" ;
4481+ out << " )" ; // concat
4482+ }
4483+
4484+ out << " )" ; // let ?withop
4485+ }
44474486 }
44484487 }
44494488 else if (expr_type.id () == ID_union || expr_type.id () == ID_union_tag)
0 commit comments