@@ -13,6 +13,7 @@ Author: Daniel Kroening, kroening@kroening.com
1313
1414#include " arith_tools.h"
1515#include " bitvector_expr.h"
16+ #include " byte_operators.h"
1617#include " c_types.h"
1718#include " config.h"
1819#include " magic.h"
@@ -344,6 +345,27 @@ optionalt<exprt> expr_initializer(
344345 return expr_initializert (ns)(type, source_location, init_byte_expr);
345346}
346347
348+ // / Typecast the input to the output if this is a signed/unsigned bv.
349+ // / Perform a reinterpret cast using byte_extract otherwise.
350+ // / @param expr the expression to be casted if necessary.
351+ // / @param out_type the type to cast the expression to.
352+ // / @return the casted or reinterpreted expression.
353+ static exprt cast_or_reinterpret (const exprt &expr, const typet &out_type)
354+ {
355+ // Same type --> no cast
356+ if (expr.type () == out_type)
357+ {
358+ return expr;
359+ }
360+ if (
361+ can_cast_type<signedbv_typet>(out_type) ||
362+ can_cast_type<unsignedbv_typet>(out_type))
363+ {
364+ return typecast_exprt::conditional_cast (expr, out_type);
365+ }
366+ return make_byte_extract (expr, from_integer (0 , char_type ()), out_type);
367+ }
368+
347369// / Builds an expression of the given output type with each of its bytes
348370// / initialized to the given initialization expression.
349371// / Integer bitvector types are currently supported.
@@ -375,7 +397,7 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
375397 const auto init_size = init_type_as_bitvector->get_width ();
376398 const irep_idt init_value = to_constant_expr (init_byte_expr).get_value ();
377399
378- // Create a new BV od `output_type` size with its representation being the
400+ // Create a new BV of `output_type` size with its representation being the
379401 // replication of the init_byte_expr (padded with 0) enough times to fill.
380402 const auto output_value =
381403 make_bvrep (out_width, [&init_size, &init_value](std::size_t index) {
@@ -400,6 +422,11 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
400422 {
401423 operation_type = unsignedbv_typet{ptr_type->get_width ()};
402424 }
425+ if (
426+ const auto float_type = type_try_dynamic_cast<floatbv_typet>(output_type))
427+ {
428+ operation_type = unsignedbv_typet{float_type->get_width ()};
429+ }
403430 // Let's cast init_byte_expr to output_type.
404431 const exprt casted_init_byte_expr =
405432 typecast_exprt::conditional_cast (init_byte_expr, operation_type);
@@ -410,10 +437,10 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
410437 casted_init_byte_expr,
411438 from_integer (config.ansi_c .char_width * i, size_type ())));
412439 }
413- if (values. size () == 1 )
414- return typecast_exprt::conditional_cast ( values[0 ], output_type);
415- return typecast_exprt::conditional_cast (
416- multi_ary_exprt (ID_bitor, values, operation_type), output_type);
440+ return cast_or_reinterpret (
441+ values. size () == 1 ? values[0 ]
442+ : multi_ary_exprt (ID_bitor, values, operation_type),
443+ output_type);
417444 }
418445
419446 // Anything else. We don't know what to do with it. So, just cast.
0 commit comments