13
13
14
14
#include " arith_tools.h"
15
15
#include " bitvector_expr.h"
16
+ #include " byte_operators.h"
16
17
#include " c_types.h"
17
18
#include " config.h"
18
19
#include " magic.h"
@@ -344,6 +345,27 @@ optionalt<exprt> expr_initializer(
344
345
return expr_initializert (ns)(type, source_location, init_byte_expr);
345
346
}
346
347
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
+
347
369
// / Builds an expression of the given output type with each of its bytes
348
370
// / initialized to the given initialization expression.
349
371
// / Integer bitvector types are currently supported.
@@ -375,7 +397,7 @@ exprt duplicate_per_byte(const exprt &init_byte_expr, const typet &output_type)
375
397
const auto init_size = init_type_as_bitvector->get_width ();
376
398
const irep_idt init_value = to_constant_expr (init_byte_expr).get_value ();
377
399
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
379
401
// replication of the init_byte_expr (padded with 0) enough times to fill.
380
402
const auto output_value =
381
403
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)
400
422
{
401
423
operation_type = unsignedbv_typet{ptr_type->get_width ()};
402
424
}
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
+ }
403
430
// Let's cast init_byte_expr to output_type.
404
431
const exprt casted_init_byte_expr =
405
432
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)
410
437
casted_init_byte_expr,
411
438
from_integer (config.ansi_c .char_width * i, size_type ())));
412
439
}
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);
417
444
}
418
445
419
446
// Anything else. We don't know what to do with it. So, just cast.
0 commit comments