33 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
40 else if(a.
id() == ID_pointer && b.
id() == ID_pointer)
48 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
56 std::cout <<
"U: " <<
format(update_state_expr) <<
"\n";
57 std::cout <<
"u: " <<
format(update_state_expr.address()) <<
"\n";
58 std::cout <<
"T: " <<
format(update_state_expr.address().type()) <<
"\n";
59 std::cout <<
"E: " <<
format(evaluate_expr.
address()) <<
"\n";
70 std::cout <<
"M: ?\n";
82 update_state_expr.new_value(), evaluate_expr.
type()),
99 auto new_evaluate_expr =
100 evaluate_expr.
with_state(update_state_expr.state());
104 std::move(simplified_cond),
107 update_state_expr.new_value(), evaluate_expr.
type()),
110 std::move(simplified_new_evaluate_expr));
115 auto new_evaluate_expr = evaluate_expr.
with_state(update_state_expr.state());
116 auto simplified_new_evaluate_expr =
121 update_state_expr.new_value().type(), evaluate_expr.
type()))
134 auto simplified_same_object =
143 auto same_offset =
equal_exprt(offset_w, offset_r);
145 auto same =
and_exprt(simplified_same_object, same_offset);
147 auto simplified_same =
151 update_state_expr.new_value(), evaluate_expr.
type());
154 if_exprt(simplified_same, new_value, simplified_new_evaluate_expr);
161 return simplified_new_evaluate_expr;
164 auto object = update_state_expr.new_value();
172 std::move(simplified_same_object),
173 std::move(byte_extract),
174 std::move(simplified_new_evaluate_expr));
183 if(src.
state().
id() == ID_update_state)
189 else if(src.
state().
id() == ID_enter_scope_state)
195 else if(src.
state().
id() == ID_exit_scope_state)
202 return std::move(src);
215 if(evaluate_expr.
address() == allocate_expr.address())
221 auto symbol_expr =
symbol_exprt(identifier, object_type);
224 return std::move(evaluate_expr);
228 auto new_evaluate_expr = evaluate_expr;
229 new_evaluate_expr.
state() = allocate_expr.state();
230 return std::move(new_evaluate_expr);
233 return std::move(evaluate_expr);
243 const auto &deallocate_state_expr =
245 auto new_evaluate_expr =
246 evaluate_expr.
with_state(deallocate_state_expr.state());
247 return std::move(new_evaluate_expr);
256 const auto &enter_scope_state_expr =
258 auto new_evaluate_expr =
259 evaluate_expr.
with_state(enter_scope_state_expr.state());
260 return std::move(new_evaluate_expr);
269 const auto &exit_scope_state_expr =
271 auto new_evaluate_expr =
272 evaluate_expr.
with_state(exit_scope_state_expr.state());
273 return std::move(new_evaluate_expr);
278 if(src.
id() == ID_object_address)
280 else if(src.
id() == ID_element_address)
282 else if(src.
id() == ID_field_address)
284 else if(src.
id() == ID_plus)
287 for(
auto &op : plus_expr.operands())
288 if(op.type().id() == ID_pointer)
292 else if(src.
id() == ID_typecast)
295 if(op.type().id() == ID_pointer)
311 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
314 const auto &pointer = src.
address();
318 if(
object.
id() == ID_object_address)
322 if(identifier.starts_with(
"allocate-"))
325 else if(identifier ==
"return_value")
329 else if(identifier.starts_with(
"va_args::"))
335 const auto &symbol = ns.
lookup(identifier);
336 if(symbol.is_static_lifetime)
345 if(src.
state().
id() == ID_update_state)
352 else if(src.
state().
id() == ID_deallocate_state)
358 auto simplified_same_object =
363 simplified_same_object,
false_exprt(), new_live_object_expr);
365 else if(src.
state().
id() == ID_enter_scope_state)
377 auto simplified_same_object =
380 src.
with_state(enter_scope_state_expr.state()),
384 simplified_same_object,
true_exprt(), new_live_object_expr);
389 src.
with_state(enter_scope_state_expr.state()),
394 else if(src.
state().
id() == ID_exit_scope_state)
404 auto simplified_same_object =
407 src.
with_state(exit_scope_state_expr.state()),
411 simplified_same_object,
false_exprt(), new_live_object_expr);
416 src.
with_state(exit_scope_state_expr.state()),
422 return std::move(src);
429 const auto &pointer = src.
address();
433 if(
object.
id() == ID_object_address)
437 if(identifier.starts_with(
"allocate-"))
440 else if(identifier.starts_with(
"va_args::"))
446 const auto &symbol = ns.
lookup(identifier);
453 if(src.
state().
id() == ID_update_state)
456 return std::move(src);
459 return std::move(src);
464 const auto &pointer = src.
address();
468 if(
object.
id() == ID_object_address)
476 if(src.
state().
id() == ID_update_state)
482 else if(src.
state().
id() == ID_enter_scope_state)
487 else if(src.
state().
id() == ID_exit_scope_state)
493 return std::move(src);
500 const auto &pointer = src.
address();
504 if(
object.
id() == ID_object_address)
507 auto size_opt =
size_of_expr(object_address_expr.object_type(), ns);
508 if(size_opt.has_value())
511 return std::move(src);
516 if(src.
state().
id() == ID_update_state)
520 else if(src.
state().
id() == ID_exit_scope_state)
525 return std::move(src);
530 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
533 auto &state = src.
state();
535 auto &size = src.
size();
537 if(state.id() == ID_update_state)
546 else if(state.id() == ID_enter_scope_state)
556 auto enter_scope_address =
557 enter_scope_state_expr.object_type().id() == ID_array ?
559 enter_scope_state_expr.address();
570 pointer, enter_scope_state_expr.address(),
address_taken, ns);
573 auto simplified_same_object =
582 auto object_size_opt =
584 if(!object_size_opt.has_value())
585 return std::move(src);
595 if_exprt(simplified_same_object, simplified_upper, rec_result);
599 else if(state.id() == ID_exit_scope_state)
610 auto simplified_same_object =
626 return std::move(src);
630 static bool is_one(
const exprt &src)
632 if(src.
id() == ID_typecast)
636 auto value_opt = numeric_cast<mp_integer>(src);
637 return value_opt.has_value() && *value_opt == 1;
646 return (type.
id() == ID_signedbv || type.
id() == ID_unsignedbv) &&
657 auto integer_opt = numeric_cast<mp_integer>(src);
659 return integer_opt.has_value() && *integer_opt == 0;
664 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
668 const auto &state = src.
state();
669 const auto &pointer = src.
address();
671 if(state.id() == ID_update_state)
675 auto cstring_in_old_state = src;
676 cstring_in_old_state.
op0() = update_state_expr.state();
677 auto simplified_cstring_in_old_state =
687 return simplified_cstring_in_old_state;
693 if(update_state_expr.new_value().is_zero())
698 auto simplified_same_object =
702 simplified_same_object,
true_exprt(), simplified_cstring_in_old_state);
705 else if(state.id() == ID_enter_scope_state)
713 else if(state.id() == ID_exit_scope_state)
722 if(pointer.id() == ID_plus)
726 if(plus_expr.operands().size() == 2 && is_one(plus_expr.op1()))
729 auto new_is_cstring = src;
730 new_is_cstring.
op1() = plus_expr.
op0();
735 return or_exprt(new_is_cstring, is_zero);
740 pointer.id() == ID_address_of &&
747 pointer.id() == ID_element_address &&
757 return std::move(src);
762 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
765 const auto &state = src.
state();
766 const auto &pointer = src.
address();
768 if(state.id() == ID_update_state)
772 auto cstrlen_in_old_state = src.
with_state(update_state_expr.state());
773 auto simplified_cstrlen_in_old_state =
783 return simplified_cstrlen_in_old_state;
792 if(pointer == update_state_expr.address())
797 if(pointer.id() == ID_plus)
801 if(plus_expr.operands().size() == 2 && is_one(plus_expr.op1()))
804 auto new_is_cstring = src;
805 new_is_cstring.
op1() = plus_expr.
op0();
810 return or_exprt(new_is_cstring, is_zero);
815 pointer.id() == ID_address_of &&
824 pointer.id() == ID_element_address &&
836 return std::move(src);
841 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
845 const auto &state = src.
state();
846 const auto &head = src.
head();
847 const auto &tail = src.
tail();
854 if(head_next.has_value() && tail_prev.has_value())
857 auto head_next_simplified =
859 auto tail_prev_simplified =
861 if(head_next_simplified == tail && tail_prev_simplified == head)
866 if(state.id() == ID_update_state)
871 const auto &update_type = update_state_expr.new_value().type();
872 if(update_type != src.
head().
type())
875 auto without_update = src.
with_state(update_state_expr.state());
879 else if(state.id() == ID_enter_scope_state)
886 else if(state.id() == ID_exit_scope_state)
894 return std::move(src);
899 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
902 if(src.
pointer().
id() == ID_object_address)
907 else if(src.
pointer().
id() == ID_element_address)
912 auto size_opt =
size_of_expr(element_address_expr.element_type(), ns);
913 if(size_opt.has_value())
917 element_address_expr.index(), src.
type()),
924 return std::move(sum);
927 else if(src.
pointer().
id() == ID_address_of)
930 if(address_of_expr.object().id() == ID_string_constant)
933 else if(src.
pointer().
id() == ID_typecast)
945 return std::move(src);
950 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
955 if(src.
pointer() != simplified_pointer)
958 return std::move(src);
963 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
966 if(src.
id() == ID_allocate)
970 else if(src.
id() == ID_evaluate)
974 if(evaluate_expr.state().id() == ID_update_state)
978 else if(evaluate_expr.state().id() == ID_allocate_state)
982 else if(evaluate_expr.state().id() == ID_deallocate_state)
986 else if(evaluate_expr.state().id() == ID_enter_scope_state)
990 else if(evaluate_expr.state().id() == ID_exit_scope_state)
996 src.
id() == ID_state_r_ok || src.
id() == ID_state_w_ok ||
997 src.
id() == ID_state_rw_ok)
1001 else if(src.
id() == ID_state_live_object)
1006 else if(src.
id() == ID_state_writeable_object)
1011 else if(src.
id() == ID_state_is_cstring)
1016 else if(src.
id() == ID_state_cstrlen)
1020 else if(src.
id() == ID_state_is_sentinel_dll)
1025 else if(src.
id() == ID_state_is_dynamic_object)
1030 else if(src.
id() == ID_plus)
1034 src.
type().
id() == ID_pointer &&
1035 plus_expr.op0().id() == ID_element_address)
1039 new_element_address_expr.index() =
plus_exprt(
1040 new_element_address_expr.index(),
1042 plus_expr.op1(), new_element_address_expr.index().type()));
1043 new_element_address_expr.index() =
1049 else if(src.
id() == ID_pointer_offset)
1054 else if(src.
id() == ID_pointer_object)
1059 else if(src.
id() == ID_state_object_size)
1063 else if(src.
id() == ID_equal)
1067 equal_expr.lhs().id() == ID_pointer_object &&
1068 equal_expr.rhs().id() == ID_pointer_object)
1072 if(lhs_p.id() == ID_object_address && rhs_p.id() == ID_object_address)
1089 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
std::unordered_set< symbol_exprt, irep_hash > address_taken(const std::vector< exprt > &src)
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
byte_extract_exprt make_byte_extract(const exprt &_op, const exprt &_offset, const typet &_type)
Construct a byte_extract_exprt with endianness and byte width matching the current configuration.
bitvector_typet char_type()
allocate_exprt with_state(exprt state) const
const exprt & state() const
typet index_type() const
The type of the index expressions into any instance of this type.
A base class for relations, i.e., binary predicates whose two operands have the same type.
std::size_t get_width() const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Operator to return the address of an array element relative to a base address.
const exprt & state() const
const exprt & state() const
evaluate_exprt with_state(exprt state) const
const exprt & address() const
const exprt & state() const
Base class for all expressions.
bool is_false() const
Return whether the expression is a constant representing false.
typet & type()
Return the type of the expression.
bool is_constant() const
Return whether the expression is a constant.
The Boolean constant false.
The trinary if-then-else operator.
const irep_idt & id() const
Binary multiplication Associativity is not specified.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Operator to return the address of an object.
irep_idt object_identifier() const
The plus expression Associativity is not specified.
A numerical identifier for the object a pointer points to.
The offset (in bytes) of a pointer relative to the object.
const typet & base_type() const
The type of the data what we point to.
const exprt & address() const
const exprt & state() const
state_cstrlen_exprt with_state(exprt state) const
const exprt & address() const
const exprt & state() const
state_is_cstring_exprt with_state(exprt state) const
const exprt & address() const
state_is_dynamic_object_exprt with_state(exprt state) const
const exprt & state() const
const exprt & head() const
state_is_sentinel_dll_exprt with_state(exprt state) const
const exprt & tail() const
const exprt & state() const
const exprt & state() const
const exprt & address() const
state_live_object_exprt with_state(exprt state) const
const exprt & address() const
state_object_size_exprt with_state(exprt state) const
const exprt & state() const
const exprt & address() const
state_ok_exprt with_state(exprt state) const
const exprt & state() const
const exprt & size() const
const exprt & state() const
const exprt & address() const
Expression to hold a symbol (variable)
The Boolean constant true.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
Fixed-width bit-vector with unsigned binary interpretation.
const exprt & state() const
constant_exprt make_boolean_expr(bool value)
returns true_exprt if given true and false_exprt otherwise
Deprecated expression utility functions.
static exprt implication(exprt lhs, exprt rhs)
std::optional< exprt > may_alias(const exprt &a, const exprt &b, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt may_be_same_object(const exprt &a, const exprt &b, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
const pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const element_address_exprt & to_element_address_expr(const exprt &expr)
Cast an exprt to an element_address_exprt.
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
exprt pointer_offset(const exprt &pointer)
exprt object_size(const exprt &pointer)
exprt same_object(const exprt &p1, const exprt &p2)
Various predicates over pointers in programs.
std::optional< exprt > sentinel_dll_next(const exprt &state, const exprt &node, const namespacet &ns)
std::optional< exprt > sentinel_dll_prev(const exprt &state, const exprt &node, const namespacet &ns)
const state_is_sentinel_dll_exprt & to_state_is_sentinel_dll_expr(const exprt &expr)
Cast an exprt to a state_is_sentinel_dll_exprt.
exprt simplify_expr(exprt src, const namespacet &ns)
exprt simplify_evaluate_enter_scope_state(evaluate_exprt evaluate_expr, const namespacet &ns)
exprt simplify_allocate(allocate_exprt src)
exprt simplify_is_dynamic_object_expr(state_is_dynamic_object_exprt src)
exprt simplify_object_expression_rec(exprt src)
static bool is_zero_char(const exprt &src, const namespacet &ns)
exprt simplify_live_object_expr(state_live_object_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_is_sentinel_dll_expr(state_is_sentinel_dll_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_evaluate_exit_scope_state(evaluate_exprt evaluate_expr, const namespacet &ns)
exprt simplify_ok_expr(state_ok_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_state_expr_node(exprt, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &)
exprt simplify_is_cstring_expr(state_is_cstring_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_evaluate_update(evaluate_exprt evaluate_expr, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_cstrlen_expr(state_cstrlen_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
std::size_t allocate_counter
exprt simplify_pointer_offset_expr(pointer_offset_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
static bool is_a_char_type(const typet &type)
exprt simplify_evaluate_deallocate_state(evaluate_exprt evaluate_expr, const namespacet &ns)
exprt simplify_object_expression(exprt src)
exprt simplify_object_size_expr(state_object_size_exprt src, const namespacet &ns)
exprt simplify_state_expr(exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_writeable_object_expr(state_writeable_object_exprt src, const namespacet &ns)
exprt simplify_pointer_object_expr(pointer_object_exprt src, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &ns)
exprt simplify_evaluate_allocate_state(evaluate_exprt evaluate_expr, const namespacet &ns)
static bool types_are_compatible(const typet &a, const typet &b)
Simplify State Expression.
#define PRECONDITION(CONDITION)
const deallocate_state_exprt & to_deallocate_state_expr(const exprt &expr)
Cast an exprt to a deallocate_state_exprt.
const state_cstrlen_exprt & to_state_cstrlen_expr(const exprt &expr)
Cast an exprt to a state_cstrlen_exprt.
const update_state_exprt & to_update_state_expr(const exprt &expr)
Cast an exprt to a update_state_exprt.
const state_is_dynamic_object_exprt & to_state_is_dynamic_object_expr(const exprt &expr)
Cast an exprt to a state_is_dynamic_object_exprt.
const evaluate_exprt & to_evaluate_expr(const exprt &expr)
Cast an exprt to a evaluate_exprt.
const state_object_size_exprt & to_state_object_size_expr(const exprt &expr)
Cast an exprt to a state_object_size_exprt.
const allocate_exprt & to_allocate_expr(const exprt &expr)
Cast an exprt to a allocate_exprt.
const state_live_object_exprt & to_state_live_object_expr(const exprt &expr)
Cast an exprt to a state_live_object_exprt.
const state_writeable_object_exprt & to_state_writeable_object_expr(const exprt &expr)
Cast an exprt to a state_writeable_object_exprt.
const state_is_cstring_exprt & to_state_is_cstring_expr(const exprt &expr)
Cast an exprt to a state_is_cstring_exprt.
const exit_scope_state_exprt & to_exit_scope_state_expr(const exprt &expr)
Cast an exprt to a exit_scope_state_exprt.
const enter_scope_state_exprt & to_enter_scope_state_expr(const exprt &expr)
Cast an exprt to a enter_scope_state_exprt.
const state_ok_exprt & to_state_ok_expr(const exprt &expr)
Cast an exprt to a state_ok_exprt.
API to expression classes.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.