53 bool seen_symbol =
false;
56 if(it->id() == ID_symbol)
70 const std::vector<exprt> &points_to_set,
71 const std::vector<exprt> &retained_values,
76 json_result[
"PointsToSetSize"] =
80 for(
const auto &
object : points_to_set)
85 json_result[
"PointsToSet"] = points_to_set_json;
87 json_result[
"RetainedValuesSetSize"] =
91 for(
auto &retained_value : retained_values)
97 json_result[
"RetainedValuesSet"] = retained_values_set_json;
107 static std::optional<exprt>
110 if(
const auto *index_expr = expr_try_dynamic_cast<index_exprt>(expr))
116 offset_elements, index_expr->index().
type())}};
118 else if(
const auto *if_expr = expr_try_dynamic_cast<if_exprt>(expr))
120 const auto true_case =
124 const auto false_case =
128 return if_exprt{if_expr->
cond(), *true_case, *false_case};
144 const exprt &pointer,
145 bool display_points_to_sets)
148 pointer.
type().
id() == ID_pointer,
149 "dereference expected pointer type, but got " + pointer.
type().
pretty());
152 if(pointer.
id()==ID_if)
160 else if(pointer.
id() == ID_typecast)
162 const exprt *underlying = &pointer;
165 while(underlying->
id() == ID_typecast &&
166 underlying->
type().
id() == ID_pointer)
171 if(underlying->
id() == ID_if && underlying->
type().
id() == ID_pointer)
173 const auto &if_expr =
to_if_expr(*underlying);
178 display_points_to_sets),
181 display_points_to_sets));
184 else if(pointer.
id() == ID_plus && pointer.
operands().size() == 2)
195 std::swap(pointer_expr, offset_expr);
204 auto derefd_with_offset =
206 return *derefd_with_offset;
216 const exprt &pointer,
217 bool display_points_to_sets)
222 const std::vector<exprt> points_to_set =
226 const std::vector<exprt> retained_values =
231 exprt compare_against_pointer = pointer;
243 compare_against_pointer = fresh_binder.
symbol_expr();
248 .map([&](
const exprt &value) {
251 .collect<std::deque<valuet>>();
253 const bool may_fail =
255 std::any_of(values.begin(), values.end(), [](
const valuet &value) {
256 return value.value.is_nil();
268 for(
const auto &value : values)
273 result_value = value.value;
275 result_value =
if_exprt(value.pointer_guard, value.value, result_value);
279 if(compare_against_pointer != pointer)
283 if(display_points_to_sets)
287 pointer, points_to_set, retained_values, result_value);
294 const exprt &pointer,
305 failure_value = failed_symbol->symbol_expr();
306 failure_value.
set(ID_C_invalid_object,
true);
323 failure_value.
set(ID_C_invalid_object,
true);
327 result.
value = failure_value;
341 const typet &object_type,
342 const typet &dereference_type,
345 const typet *object_unwrapped = &object_type;
346 const typet *dereference_unwrapped = &dereference_type;
347 while(object_unwrapped->
id() == ID_pointer &&
348 dereference_unwrapped->
id() == ID_pointer)
351 dereference_unwrapped =
354 if(dereference_unwrapped->
id() == ID_empty)
358 else if(dereference_unwrapped->
id() == ID_pointer &&
359 object_unwrapped->
id() != ID_pointer)
362 std::cout <<
"value_set_dereference: the dereference type has "
363 "too many ID_pointer levels"
365 std::cout <<
" object_type: " << object_type.
pretty() << std::endl;
366 std::cout <<
" dereference_type: " << dereference_type.
pretty()
371 if(object_type == dereference_type)
375 const typet &ot_base = object_type.
id() == ID_struct_tag
378 const typet &dt_base = dereference_type.
id() == ID_struct_tag
382 if(ot_base.
id()==ID_struct &&
383 dt_base.
id()==ID_struct)
391 if(dereference_type.
id()==ID_code &&
392 object_type.
id()==ID_code)
396 if((dereference_type.
id()==ID_signedbv ||
397 dereference_type.
id()==ID_unsignedbv) &&
398 (object_type.
id()==ID_signedbv ||
399 object_type.
id()==ID_unsignedbv) &&
424 bool exclude_null_derefs,
427 if(what.
id() == ID_unknown || what.
id() == ID_invalid)
435 if(root_object.
id() == ID_null_object)
439 else if(root_object.
id() == ID_integer_address)
461 const exprt &pointer_expr,
465 type_checked_cast<pointer_typet>(pointer_expr.
type());
468 if(what.
id()==ID_unknown ||
469 what.
id()==ID_invalid)
475 what.
id() == ID_object_descriptor,
476 "unknown points-to: " + what.
id_string());
484 std::cout <<
"O: " <<
format(root_object) <<
'\n';
487 if(root_object.
id() == ID_null_object)
496 else if(root_object.
id()==ID_dynamic_object)
510 else if(root_object.
id()==ID_integer_address)
531 result.
value=index_expr;
586 const typet &object_type =
object.type();
587 const typet &root_object_type = root_object.
type();
611 root_object_type.
id() == ID_array &&
613 to_array_type(root_object_type).element_type(), dereference_type,
ns) &&
627 const auto offset_int =
630 if(offset_int % *element_size == 0)
635 offset_int / *element_size,
648 root_object, o.
offset(), dereference_type,
ns);
649 if(subexpr.has_value())
652 subexpr.has_value() &&
653 subexpr.value().id() != ID_byte_extract_little_endian &&
654 subexpr.value().id() != ID_byte_extract_big_endian)
658 result.
value = subexpr.value();
691 return type.
id()==ID_unsignedbv ||
692 type.
id()==ID_signedbv ||
694 type.
id()==ID_fixedbv ||
695 type.
id()==ID_floatbv ||
696 type.
id()==ID_c_enum_tag;
709 const typet &to_type,
723 (
from_type.id() == ID_pointer && to_type.
id() == ID_pointer))
732 to_type.
id() != ID_fixedbv && to_type.
id() != ID_floatbv &&
756 const typet &to_type,
763 if(
from_type.id()==ID_code || to_type.
id()==ID_code)
777 auto from_type_element_type_size =
780 : std::optional<mp_integer>{};
785 from_type.id() == ID_array && from_type_element_type_size.has_value() &&
786 *from_type_element_type_size == 1 && to_type_size.has_value() &&
787 *to_type_size == 1 &&
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.
Expression classes for byte-level operators.
pointer_typet pointer_type(const typet &subtype)
bitvector_typet char_type()
Operator to return the address of an object.
typet index_type() const
The type of the index expressions into any instance of this type.
const typet & element_type() const
The type of the elements of the array.
std::size_t get_width() const
struct configt::ansi_ct ansi_c
virtual const symbolt * get_or_create_failed_symbol(const exprt &expr)=0
virtual std::vector< exprt > get_value_set(const exprt &expr) const =0
Operator to dereference a pointer.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
depth_iteratort depth_end()
depth_iteratort depth_begin()
const source_locationt & source_location() const
bool is_zero() const
Return whether the expression is a constant representing 0.
typet & type()
Return the type of the expression.
bool is_constant() const
Return whether the expression is a constant.
The trinary if-then-else operator.
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const std::string & id_string() const
void set(const irep_idt &name, const irep_idt &value)
const irep_idt & id() const
Evaluates to true if the operand is a pointer to a dynamic object.
jsont & push_back(const jsont &json)
Class that provides messages with a built-in verbosity 'level'.
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
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().
The null pointer constant.
Split an expression into a base object and a (byte) offset.
static const exprt & root_object(const exprt &expr)
The plus expression Associativity is not specified.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
Expression to hold a symbol (variable)
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
The Boolean constant true.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
Return value for build_reference_to; see that method for documentation.
static bool memory_model_bytes(exprt &value, const typet &type, const exprt &offset, const namespacet &ns)
Replace value by an expression of type to_type corresponding to the value at memory address value + o...
valuet get_failure_value(const exprt &pointer, const typet &type)
exprt handle_dereference_base_case(const exprt &pointer, bool display_points_to_sets)
const bool exclude_null_derefs
Flag indicating whether value_set_dereferencet::dereference should disregard an apparent attempt to d...
symbol_table_baset & new_symbol_table
static bool dereference_type_compare(const typet &object_type, const typet &dereference_type, const namespacet &ns)
Check if the two types have matching number of ID_pointer levels, with the dereference type eventuall...
message_handlert & message_handler
dereference_callbackt & dereference_callback
exprt dereference(const exprt &pointer, bool display_points_to_sets=false)
Dereference the given pointer-expression.
const irep_idt language_mode
language_mode: ID_java, ID_C or another language identifier if we know the source language in use,...
static valuet build_reference_to(const exprt &what, const exprt &pointer, const namespacet &ns)
static bool should_ignore_value(const exprt &what, bool exclude_null_derefs, const irep_idt &language_mode)
Determine whether possible alias what should be ignored when replacing a pointer by its referees.
static bool memory_model(exprt &value, const typet &type, const exprt &offset, const namespacet &ns)
Replace value by an expression of type to_type corresponding to the value at memory address value + o...
Forward depth-first search iterators These iterators' copy operations are expensive,...
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Deprecated expression utility functions.
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Fresh auxiliary symbol creation.
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
API to expression classes for Pointers.
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const object_descriptor_exprt & to_object_descriptor_expr(const exprt &expr)
Cast an exprt to an object_descriptor_exprt.
std::optional< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
std::optional< exprt > get_subexpression_at_offset(const exprt &expr, const mp_integer &offset_bytes, const typet &target_type_raw, const namespacet &ns)
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
exprt pointer_offset(const exprt &pointer)
exprt same_object(const exprt &p1, const exprt &p2)
Various predicates over pointers in programs.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
bool simplify(exprt &expr, const namespacet &ns)
exprt simplify_expr(exprt src, const namespacet &ns)
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
#define CHECK_RETURN(CONDITION)
bool can_cast_expr< typecast_exprt >(const exprt &base)
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
bool can_cast_expr< constant_exprt >(const exprt &base)
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
static bool is_a_bv_type(const typet &type)
static json_objectt value_set_dereference_stats_to_json(const exprt &pointer, const std::vector< exprt > &points_to_set, const std::vector< exprt > &retained_values, const exprt &value)
static bool should_use_local_definition_for(const exprt &expr)
Returns true if expr is complicated enough that a local definition (using a let expression) is prefer...
static std::optional< exprt > try_add_offset_to_indices(const exprt &expr, const exprt &offset_elements)
If expr is of the form (c1 ? e1[o1] : c2 ? e2[o2] : c3 ? ...) then return c1 ? e1[o1 + offset] : e2[o...