@@ -434,17 +434,20 @@ static exprt::operandst instantiate_byte_array(
434
434
src.operands ().begin () + narrow_cast<std::ptrdiff_t >(upper_bound)};
435
435
}
436
436
437
- PRECONDITION (src.type ().id () == ID_array || src.type ().id () == ID_vector);
437
+ const typet &element_type = src.type ().id () == ID_array
438
+ ? to_array_type (src.type ()).element_type ()
439
+ : to_vector_type (src.type ()).element_type ();
440
+ const typet index_type = src.type ().id () == ID_array
441
+ ? to_array_type (src.type ()).index_type ()
442
+ : to_vector_type (src.type ()).index_type ();
438
443
PRECONDITION (
439
- can_cast_type<bitvector_typet>(
440
- to_type_with_subtype (src.type ()).subtype ()) &&
441
- to_bitvector_type (to_type_with_subtype (src.type ()).subtype ()).get_width () ==
442
- bits_per_byte);
444
+ can_cast_type<bitvector_typet>(element_type) &&
445
+ to_bitvector_type (element_type).get_width () == bits_per_byte);
443
446
exprt::operandst bytes;
444
447
bytes.reserve (upper_bound - lower_bound);
445
448
for (std::size_t i = lower_bound; i < upper_bound; ++i)
446
449
{
447
- const index_exprt idx{src, from_integer (i, c_index_type () )};
450
+ const index_exprt idx{src, from_integer (i, index_type )};
448
451
bytes.push_back (simplify_expr (idx, ns));
449
452
}
450
453
return bytes;
@@ -465,19 +468,22 @@ static exprt unpack_array_vector_no_known_bounds(
465
468
const std::size_t bits_per_byte,
466
469
const namespacet &ns)
467
470
{
471
+ const typet index_type = src.type ().id () == ID_array
472
+ ? to_array_type (src.type ()).index_type ()
473
+ : to_vector_type (src.type ()).index_type ();
474
+
468
475
// TODO we either need a symbol table here or make array comprehensions
469
476
// introduce a scope
470
477
static std::size_t array_comprehension_index_counter = 0 ;
471
478
++array_comprehension_index_counter;
472
479
symbol_exprt array_comprehension_index{
473
480
" $array_comprehension_index_a_v" +
474
481
std::to_string (array_comprehension_index_counter),
475
- c_index_type () };
482
+ index_type };
476
483
477
484
index_exprt element{
478
485
src,
479
- div_exprt{
480
- array_comprehension_index, from_integer (el_bytes, c_index_type ())}};
486
+ div_exprt{array_comprehension_index, from_integer (el_bytes, index_type)}};
481
487
482
488
exprt sub =
483
489
unpack_rec (element, little_endian, {}, {}, bits_per_byte, ns, false );
@@ -577,6 +583,9 @@ static exprt unpack_array_vector(
577
583
num_elements = *max_bytes;
578
584
579
585
const exprt src_simp = simplify_expr (src, ns);
586
+ const typet index_type = src_simp.type ().id () == ID_array
587
+ ? to_array_type (src_simp.type ()).index_type ()
588
+ : to_vector_type (src_simp.type ()).index_type ();
580
589
581
590
for (mp_integer i = first_element; i < *num_elements; ++i)
582
591
{
@@ -591,7 +600,7 @@ static exprt unpack_array_vector(
591
600
}
592
601
else
593
602
{
594
- element = index_exprt (src_simp, from_integer (i, c_index_type () ));
603
+ element = index_exprt (src_simp, from_integer (i, index_type ));
595
604
}
596
605
597
606
// recursively unpack each element so that we eventually just have an array
@@ -1022,14 +1031,17 @@ static exprt unpack_rec(
1022
1031
src, bv_typet{numeric_cast_v<std::size_t >(total_bits)});
1023
1032
auto const byte_type = bv_typet{bits_per_byte};
1024
1033
exprt::operandst byte_operands;
1034
+ array_typet array_type{
1035
+ bv_typet{bits_per_byte}, from_integer (0 , size_type ())};
1036
+
1025
1037
for (; bit_offset < last_bit; bit_offset += bits_per_byte)
1026
1038
{
1027
1039
PRECONDITION (
1028
1040
pointer_offset_bits (src_as_bitvector.type (), ns).has_value ());
1029
1041
extractbits_exprt extractbits (
1030
1042
src_as_bitvector,
1031
- from_integer (bit_offset + bits_per_byte - 1 , c_index_type ()),
1032
- from_integer (bit_offset, c_index_type ()),
1043
+ from_integer (bit_offset + bits_per_byte - 1 , array_type. index_type ()),
1044
+ from_integer (bit_offset, array_type. index_type ()),
1033
1045
byte_type);
1034
1046
1035
1047
// endianness_mapt should be the point of reference for mapping out
@@ -1042,9 +1054,8 @@ static exprt unpack_rec(
1042
1054
}
1043
1055
1044
1056
const std::size_t size = byte_operands.size ();
1045
- return array_exprt (
1046
- std::move (byte_operands),
1047
- array_typet{bv_typet{bits_per_byte}, from_integer (size, size_type ())});
1057
+ array_type.size () = from_integer (size, size_type ());
1058
+ return array_exprt{std::move (byte_operands), std::move (array_type)};
1048
1059
}
1049
1060
1050
1061
return array_exprt (
@@ -1112,7 +1123,7 @@ static exprt lower_byte_extract_array_vector(
1112
1123
symbol_exprt array_comprehension_index{
1113
1124
" $array_comprehension_index_a" +
1114
1125
std::to_string (array_comprehension_index_counter),
1115
- c_index_type ()};
1126
+ array_type. index_type ()};
1116
1127
1117
1128
plus_exprt new_offset{
1118
1129
unpacked.offset (),
@@ -1347,10 +1358,17 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
1347
1358
const exprt &offset = unpacked.offset ();
1348
1359
1349
1360
optionalt<typet> subtype;
1361
+ optionalt<typet> index_type;
1350
1362
if (root.type ().id () == ID_vector)
1363
+ {
1351
1364
subtype = to_vector_type (root.type ()).element_type ();
1365
+ index_type = to_vector_type (root.type ()).index_type ();
1366
+ }
1352
1367
else
1368
+ {
1353
1369
subtype = to_array_type (root.type ()).element_type ();
1370
+ index_type = to_array_type (root.type ()).index_type ();
1371
+ }
1354
1372
1355
1373
auto subtype_bits = pointer_offset_bits (*subtype, ns);
1356
1374
@@ -1383,7 +1401,9 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
1383
1401
// the most significant byte comes first in the concatenation!
1384
1402
std::size_t offset_int = little_endian ? (width_bytes - i - 1 ) : i;
1385
1403
1386
- plus_exprt offset_i (from_integer (offset_int, offset.type ()), offset);
1404
+ plus_exprt offset_i{
1405
+ from_integer (offset_int, *index_type),
1406
+ typecast_exprt::conditional_cast (offset, *index_type)};
1387
1407
simplify (offset_i, ns);
1388
1408
1389
1409
mp_integer index = 0 ;
@@ -1447,7 +1467,7 @@ static exprt lower_byte_update_byte_array_vector_non_const(
1447
1467
symbol_exprt array_comprehension_index{
1448
1468
" $array_comprehension_index_u_a_v" +
1449
1469
std::to_string (array_comprehension_index_counter),
1450
- c_index_type ()};
1470
+ to_array_type (src. type ()). index_type ()};
1451
1471
1452
1472
binary_predicate_exprt lower_bound{
1453
1473
typecast_exprt::conditional_cast (
@@ -1514,6 +1534,10 @@ static exprt lower_byte_update_byte_array_vector(
1514
1534
src.id () == ID_byte_update_big_endian);
1515
1535
const bool little_endian = src.id () == ID_byte_update_little_endian;
1516
1536
1537
+ const typet index_type = src.type ().id () == ID_array
1538
+ ? to_array_type (src.type ()).index_type ()
1539
+ : to_vector_type (src.type ()).index_type ();
1540
+
1517
1541
// apply 'array-update-with' num_elements times
1518
1542
exprt result = src.op ();
1519
1543
@@ -1522,7 +1546,10 @@ static exprt lower_byte_update_byte_array_vector(
1522
1546
const exprt &element = value_as_byte_array.operands ()[i];
1523
1547
1524
1548
exprt where = simplify_expr (
1525
- plus_exprt{src.offset (), from_integer (i, src.offset ().type ())}, ns);
1549
+ plus_exprt{
1550
+ typecast_exprt::conditional_cast (src.offset (), index_type),
1551
+ from_integer (i, index_type)},
1552
+ ns);
1526
1553
1527
1554
// skip elements that wouldn't change (skip over typecasts as we might have
1528
1555
// some signed/unsigned char conversions)
@@ -1593,9 +1620,10 @@ static exprt lower_byte_update_array_vector_unbounded(
1593
1620
symbol_exprt array_comprehension_index{
1594
1621
" $array_comprehension_index_u_a_v_u" +
1595
1622
std::to_string (array_comprehension_index_counter),
1596
- c_index_type ()};
1623
+ to_array_type (src. type ()). index_type ()};
1597
1624
1598
1625
// all arithmetic uses offset/index types
1626
+ PRECONDITION (array_comprehension_index.type () == src.offset ().type ());
1599
1627
PRECONDITION (subtype_size.type () == src.offset ().type ());
1600
1628
PRECONDITION (initial_bytes.type () == src.offset ().type ());
1601
1629
PRECONDITION (first_index.type () == src.offset ().type ());
@@ -1727,6 +1755,8 @@ static exprt lower_byte_update_array_vector_non_const(
1727
1755
1728
1756
// compute the index of the first element of the array/vector that may be
1729
1757
// updated
1758
+ PRECONDITION (
1759
+ src.offset ().type () == to_array_type (src.op ().type ()).index_type ());
1730
1760
exprt first_index = div_exprt{src.offset (), subtype_size};
1731
1761
simplify (first_index, ns);
1732
1762
@@ -1862,10 +1892,17 @@ static exprt lower_byte_update_array_vector(
1862
1892
{
1863
1893
const bool is_array = src.type ().id () == ID_array;
1864
1894
exprt size;
1895
+ typet index_type;
1865
1896
if (is_array)
1897
+ {
1866
1898
size = to_array_type (src.type ()).size ();
1899
+ index_type = to_array_type (src.type ()).index_type ();
1900
+ }
1867
1901
else
1902
+ {
1868
1903
size = to_vector_type (src.type ()).size ();
1904
+ index_type = to_vector_type (src.type ()).index_type ();
1905
+ }
1869
1906
1870
1907
auto subtype_bits = pointer_offset_bits (subtype, ns);
1871
1908
@@ -1894,7 +1931,7 @@ static exprt lower_byte_update_array_vector(
1894
1931
(i + 1 ) * *subtype_bits <= offset_bytes * src.get_bits_per_byte ();
1895
1932
++i)
1896
1933
{
1897
- elements.push_back (index_exprt{src.op (), from_integer (i, c_index_type () )});
1934
+ elements.push_back (index_exprt{src.op (), from_integer (i, index_type )});
1898
1935
}
1899
1936
1900
1937
// the modified elements
@@ -1932,7 +1969,7 @@ static exprt lower_byte_update_array_vector(
1932
1969
1933
1970
const byte_update_exprt bu{
1934
1971
src.id (),
1935
- index_exprt{src.op (), from_integer (i, c_index_type () )},
1972
+ index_exprt{src.op (), from_integer (i, index_type )},
1936
1973
from_integer (update_offset < 0 ? 0 : update_offset, src.offset ().type ()),
1937
1974
array_exprt{
1938
1975
std::move (update_values),
@@ -1945,7 +1982,7 @@ static exprt lower_byte_update_array_vector(
1945
1982
1946
1983
// copy the tail not affected by the update
1947
1984
for (; i < num_elements; ++i)
1948
- elements.push_back (index_exprt{src.op (), from_integer (i, c_index_type () )});
1985
+ elements.push_back (index_exprt{src.op (), from_integer (i, index_type )});
1949
1986
1950
1987
if (is_array)
1951
1988
return simplify_expr (
0 commit comments