@@ -418,6 +418,59 @@ static exprt::operandst instantiate_byte_array(
418
418
return bytes;
419
419
}
420
420
421
+ // / Rewrite an array or vector into its individual bytes when no maximum number
422
+ // / of bytes is known.
423
+ // / \param src: array/vector to unpack
424
+ // / \param el_bytes: byte width of array/vector elements
425
+ // / \param little_endian: true, iff assumed endianness is little-endian
426
+ // / \param ns: namespace for type lookups
427
+ // / \return Array expression holding unpacked elements or array comprehension
428
+ static exprt unpack_array_vector_no_known_bounds (
429
+ const exprt &src,
430
+ std::size_t el_bytes,
431
+ bool little_endian,
432
+ const namespacet &ns)
433
+ {
434
+ // TODO we either need a symbol table here or make array comprehensions
435
+ // introduce a scope
436
+ static std::size_t array_comprehension_index_counter = 0 ;
437
+ ++array_comprehension_index_counter;
438
+ symbol_exprt array_comprehension_index{
439
+ " $array_comprehension_index_a_v" +
440
+ std::to_string (array_comprehension_index_counter),
441
+ index_type ()};
442
+
443
+ index_exprt element{
444
+ src,
445
+ div_exprt{array_comprehension_index, from_integer (el_bytes, index_type ())}};
446
+
447
+ exprt sub = unpack_rec (element, little_endian, {}, {}, ns, false );
448
+ exprt::operandst sub_operands = instantiate_byte_array (sub, 0 , el_bytes, ns);
449
+
450
+ exprt body = sub_operands.front ();
451
+ const mod_exprt offset{
452
+ array_comprehension_index,
453
+ from_integer (el_bytes, array_comprehension_index.type ())};
454
+ for (std::size_t i = 1 ; i < el_bytes; ++i)
455
+ {
456
+ body = if_exprt{
457
+ equal_exprt{offset, from_integer (i, array_comprehension_index.type ())},
458
+ sub_operands[i],
459
+ body};
460
+ }
461
+
462
+ const exprt array_vector_size = src.type ().id () == ID_vector
463
+ ? to_vector_type (src.type ()).size ()
464
+ : to_array_type (src.type ()).size ();
465
+
466
+ return array_comprehension_exprt{
467
+ std::move (array_comprehension_index),
468
+ std::move (body),
469
+ array_typet{bv_typet{8 },
470
+ mult_exprt{array_vector_size,
471
+ from_integer (el_bytes, array_vector_size.type ())}}};
472
+ }
473
+
421
474
// / Rewrite an array or vector into its individual bytes.
422
475
// / \param src: array/vector to unpack
423
476
// / \param src_size: array/vector size; if not a constant and thus not set,
@@ -445,47 +498,11 @@ static exprt unpack_array_vector(
445
498
446
499
if (!src_size.has_value () && !max_bytes.has_value ())
447
500
{
448
- // TODO we either need a symbol table here or make array comprehensions
449
- // introduce a scope
450
- static std::size_t array_comprehension_index_counter = 0 ;
451
- ++array_comprehension_index_counter;
452
- symbol_exprt array_comprehension_index{
453
- " $array_comprehension_index_a_v" +
454
- std::to_string (array_comprehension_index_counter),
455
- index_type ()};
456
-
457
- CHECK_RETURN (el_bytes > 0 );
458
- index_exprt element{src,
459
- div_exprt{array_comprehension_index,
460
- from_integer (el_bytes, index_type ())}};
461
-
462
- exprt sub = unpack_rec (element, little_endian, {}, {}, ns, false );
463
- exprt::operandst sub_operands =
464
- instantiate_byte_array (sub, 0 , el_bytes, ns);
465
-
466
- exprt body = sub_operands.front ();
467
- const mod_exprt offset{
468
- array_comprehension_index,
469
- from_integer (el_bytes, array_comprehension_index.type ())};
470
- for (std::size_t i = 1 ; i < el_bytes; ++i)
471
- {
472
- body = if_exprt{
473
- equal_exprt{offset, from_integer (i, array_comprehension_index.type ())},
474
- sub_operands[i],
475
- body};
476
- }
477
-
478
- const exprt array_vector_size = src.type ().id () == ID_vector
479
- ? to_vector_type (src.type ()).size ()
480
- : to_array_type (src.type ()).size ();
481
-
482
- return array_comprehension_exprt{
483
- std::move (array_comprehension_index),
484
- std::move (body),
485
- array_typet{
486
- bv_typet{8 },
487
- mult_exprt{array_vector_size,
488
- from_integer (el_bytes, array_vector_size.type ())}}};
501
+ PRECONDITION_WITH_DIAGNOSTICS (
502
+ el_bytes > 0 && element_bits % 8 == 0 ,
503
+ " unpacking of arrays with non-byte-aligned elements is not supported" );
504
+ return unpack_array_vector_no_known_bounds (
505
+ src, el_bytes, little_endian, ns);
489
506
}
490
507
491
508
exprt::operandst byte_operands;
0 commit comments