|
1 | 1 | #include "symex_shadow_memory_util.h"
|
2 | 2 |
|
3 |
| -#include <langapi/language_util.h> |
4 |
| - |
5 | 3 | #include <util/arith_tools.h>
|
6 | 4 | #include <util/bitvector_expr.h>
|
| 5 | +#include <util/byte_operators.h> |
7 | 6 | #include <util/c_types.h>
|
| 7 | +#include <util/config.h> |
| 8 | +#include <util/expr_initializer.h> |
8 | 9 | #include <util/format_expr.h>
|
9 | 10 | #include <util/pointer_expr.h>
|
10 |
| -#include <util/expr_initializer.h> |
| 11 | + |
| 12 | +#include <langapi/language_util.h> |
11 | 13 |
|
12 | 14 | void log_exact_match(
|
13 | 15 | const namespacet &ns,
|
@@ -315,6 +317,18 @@ const exprt &get_field_init_expr(
|
315 | 317 | return field_type_it->second;
|
316 | 318 | }
|
317 | 319 |
|
| 320 | +static exprt conditional_cast_floatbv_to_unsignedbv(const exprt &value) |
| 321 | +{ |
| 322 | + if(value.type().id() != ID_floatbv) |
| 323 | + { |
| 324 | + return value; |
| 325 | + } |
| 326 | + return make_byte_extract( |
| 327 | + value, |
| 328 | + from_integer(0, unsigned_int_type()), |
| 329 | + unsignedbv_typet(to_bitvector_type(value.type()).get_width())); |
| 330 | +} |
| 331 | + |
318 | 332 | static void max_element(
|
319 | 333 | const exprt &element,
|
320 | 334 | const typet &field_type,
|
@@ -348,13 +362,14 @@ static void max_over_bytes(
|
348 | 362 | }
|
349 | 363 |
|
350 | 364 | static void max_elements(
|
351 |
| - const exprt &element, |
| 365 | + exprt element, |
352 | 366 | const typet &field_type,
|
353 | 367 | const namespacet &ns,
|
354 | 368 | const messaget &log,
|
355 | 369 | const bool is_union,
|
356 | 370 | exprt &max)
|
357 | 371 | {
|
| 372 | + element = conditional_cast_floatbv_to_unsignedbv(element); |
358 | 373 | if(element.type().id() == ID_unsignedbv || element.type().id() == ID_signedbv)
|
359 | 374 | {
|
360 | 375 | if(is_union)
|
@@ -432,7 +447,9 @@ exprt compute_max_over_cells(
|
432 | 447 | << messaget::eom;
|
433 | 448 | }
|
434 | 449 | }
|
435 |
| - return typecast_exprt::conditional_cast(expr, field_type); |
| 450 | + // TODO: This is incorrect when accessing non-0 offsets of scalars. |
| 451 | + return typecast_exprt::conditional_cast( |
| 452 | + conditional_cast_floatbv_to_unsignedbv(expr), field_type); |
436 | 453 | }
|
437 | 454 |
|
438 | 455 | static void or_over_bytes(
|
@@ -462,13 +479,14 @@ static exprt or_values(const exprt::operandst &values, const typet &field_type)
|
462 | 479 | }
|
463 | 480 |
|
464 | 481 | static void or_elements(
|
465 |
| - const exprt &element, |
| 482 | + exprt element, |
466 | 483 | const typet &field_type,
|
467 | 484 | const namespacet &ns,
|
468 | 485 | const messaget &log,
|
469 | 486 | const bool is_union,
|
470 | 487 | exprt::operandst &values)
|
471 | 488 | {
|
| 489 | + element = conditional_cast_floatbv_to_unsignedbv(element); |
472 | 490 | if(element.type().id() == ID_unsignedbv || element.type().id() == ID_signedbv)
|
473 | 491 | {
|
474 | 492 | exprt value = element;
|
@@ -511,7 +529,7 @@ exprt compute_or_over_cells(
|
511 | 529 | continue;
|
512 | 530 | }
|
513 | 531 | or_elements(
|
514 |
| - member_exprt(expr, component), |
| 532 | + member_exprt(expr, component), |
515 | 533 | field_type,
|
516 | 534 | ns,
|
517 | 535 | log,
|
@@ -550,11 +568,13 @@ exprt compute_or_over_cells(
|
550 | 568 | exprt::operandst values;
|
551 | 569 | if(is_union)
|
552 | 570 | {
|
553 |
| - or_over_bytes(expr, type, field_type, values); |
| 571 | + or_over_bytes( |
| 572 | + conditional_cast_floatbv_to_unsignedbv(expr), type, field_type, values); |
554 | 573 | }
|
555 | 574 | else
|
556 | 575 | {
|
557 |
| - values.push_back(typecast_exprt::conditional_cast(expr, field_type)); |
| 576 | + values.push_back(typecast_exprt::conditional_cast( |
| 577 | + conditional_cast_floatbv_to_unsignedbv(expr), field_type)); |
558 | 578 | }
|
559 | 579 | return or_values(values, field_type);
|
560 | 580 | }
|
|
0 commit comments