|
14 | 14 | #include <cassert>
|
15 | 15 | #include <memory>
|
16 | 16 |
|
| 17 | +#include <pointer-analysis/value_set_dereference.h> |
| 18 | + |
17 | 19 | #include <util/exception_utils.h>
|
18 | 20 | #include <util/expr_iterator.h>
|
19 | 21 | #include <util/expr_util.h>
|
@@ -581,52 +583,6 @@ find_unique_pointer_typed_symbol(const exprt &expr)
|
581 | 583 | return return_value;
|
582 | 584 | }
|
583 | 585 |
|
584 |
| -/// This is a simplified version of value_set_dereferencet::build_reference_to. |
585 |
| -/// It ignores the ID_dynamic_object case (which doesn't occur in goto-symex) |
586 |
| -/// and gives up for integer addresses and non-trivial symbols |
587 |
| -/// \param value_set_element: An element of a value-set |
588 |
| -/// \param type: the type of the expression that might point to |
589 |
| -/// \p value_set_element |
590 |
| -/// \return An expression for the value of the pointer indicated by \p |
591 |
| -/// value_set_element if it is easy to determine, or an empty optionalt |
592 |
| -/// otherwise |
593 |
| -static optionalt<exprt> |
594 |
| -value_set_element_to_expr(exprt value_set_element, pointer_typet type) |
595 |
| -{ |
596 |
| - const object_descriptor_exprt *object_descriptor = |
597 |
| - expr_try_dynamic_cast<object_descriptor_exprt>(value_set_element); |
598 |
| - if(!object_descriptor) |
599 |
| - { |
600 |
| - return {}; |
601 |
| - } |
602 |
| - |
603 |
| - const exprt &root_object = object_descriptor->root_object(); |
604 |
| - const exprt &object = object_descriptor->object(); |
605 |
| - |
606 |
| - if(root_object.id() == ID_null_object) |
607 |
| - { |
608 |
| - return null_pointer_exprt{type}; |
609 |
| - } |
610 |
| - else if(root_object.id() == ID_integer_address) |
611 |
| - { |
612 |
| - return {}; |
613 |
| - } |
614 |
| - else |
615 |
| - { |
616 |
| - // We should do something like |
617 |
| - // value_set_dereference::dereference_type_compare, which deals with |
618 |
| - // arrays having types containing void |
619 |
| - if(object_descriptor->offset().is_zero() && object.type() == type.subtype()) |
620 |
| - { |
621 |
| - return address_of_exprt(object); |
622 |
| - } |
623 |
| - else |
624 |
| - { |
625 |
| - return {}; |
626 |
| - } |
627 |
| - } |
628 |
| -} |
629 |
| - |
630 | 586 | void goto_symext::try_filter_value_sets(
|
631 | 587 | goto_symex_statet &state,
|
632 | 588 | exprt condition,
|
@@ -661,18 +617,29 @@ void goto_symext::try_filter_value_sets(
|
661 | 617 | // used if the condition is false, and vice versa.
|
662 | 618 | for(const auto &value_set_element : value_set_elements)
|
663 | 619 | {
|
664 |
| - optionalt<exprt> possible_value = |
665 |
| - value_set_element_to_expr(value_set_element, symbol_type); |
666 |
| - |
667 |
| - if(!possible_value) |
| 620 | + const bool exclude_null_derefs = false; |
| 621 | + value_set_dereferencet::valuet possible_value = |
| 622 | + value_set_dereferencet::build_reference_to( |
| 623 | + value_set_element, |
| 624 | + *symbol_expr, |
| 625 | + exclude_null_derefs, |
| 626 | + language_mode, |
| 627 | + ns); |
| 628 | + |
| 629 | + if(possible_value.ignore) |
668 | 630 | {
|
669 | 631 | continue;
|
670 | 632 | }
|
671 | 633 |
|
| 634 | + exprt replacement_expr = |
| 635 | + possible_value.value.is_nil() |
| 636 | + ? static_cast<exprt>(null_pointer_exprt{symbol_type}) |
| 637 | + : static_cast<exprt>(address_of_exprt{possible_value.value}); |
| 638 | + |
672 | 639 | exprt modified_condition(condition);
|
673 | 640 |
|
674 | 641 | address_of_aware_replace_symbolt replace_symbol{};
|
675 |
| - replace_symbol.insert(*symbol_expr, *possible_value); |
| 642 | + replace_symbol.insert(*symbol_expr, replacement_expr); |
676 | 643 | replace_symbol(modified_condition);
|
677 | 644 |
|
678 | 645 | // This do_simplify() is needed for the following reason: if `condition` is
|
|
0 commit comments