@@ -418,6 +418,59 @@ static exprt::operandst instantiate_byte_array(
418418 return bytes;
419419}
420420
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+
421474// / Rewrite an array or vector into its individual bytes.
422475// / \param src: array/vector to unpack
423476// / \param src_size: array/vector size; if not a constant and thus not set,
@@ -445,47 +498,11 @@ static exprt unpack_array_vector(
445498
446499 if (!src_size.has_value () && !max_bytes.has_value ())
447500 {
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);
489506 }
490507
491508 exprt::operandst byte_operands;
0 commit comments