1/*******************************************************************\
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
35 if(
comp.get_name() == member)
45 else if(
comp.is_boolean())
74 for(
const auto &
comp : components)
76 if(
comp.get_name()==member)
90std::optional<mp_integer>
101std::optional<mp_integer>
110 // get size - we can only distinguish the elements if the size is constant
112 if(!size.has_value())
115 return (*sub) * (*size);
127 return (*sub) * size;
145 const typet &subtype =
c.type();
195 // the following is an MS extension
224 // need to distinguish structs and unions
252 if(
c.get_name() == member)
264 else if(
c.is_boolean())
275 bit_field_bits == 0,
"padding ensures offset at byte boundaries");
276 const typet &subtype =
c.type();
279 return {};
// give up
311 // special-case vectors of bits
365 // flexible array members do not change the sizeof result
371 bit_field_bits == 0,
"padding ensures offset at byte boundaries");
372 const typet &subtype =
c.type();
394 const typet &subtype =
c.type();
460 // bool is a mathematical type, and has no memory layout
465 // the following is an MS extension
493 // these shouldn't really have sizes but this will do
523 // we ignore array_type->size().is_zero() for now as there may be
524 // out-of-bounds accesses that we need to model
535std::optional<mp_integer>
551 "index into array expected, found " +
565 return (*o) + (*i) * (*sub_size);
597 return {};
// don't know
634 // if this member completely contains the target, and this member is
635 // byte-aligned, recurse into it
660 // no arrays of non-byte-aligned, zero-, or unknown-sized objects
674 // only recurse if the cell completely contains the target
705 // if this member completely contains the target, recurse into it
734 const typet &target_type,
741 // offset is not a constant; try to see whether it is a multiple of a
742 // constant, or a sum that involves a multiple of a constant
749 // no arrays of zero-, or unknown-sized elements, or ones where elements
750 // have a bit-width that isn't a multiple of bytes
763 // If we have an offset C + x (where C is a constant) we can try to
764 // recurse by first looking at the member at offset C.
792 // If we have an offset that is a sum of multiplications of the form K * i
793 // or i * K (where K is a constant) then try to recurse while removing one
794 // element from this sum.
823 // give up if the offset expression isn't of the form K * i or i * K
824 // (where K is a constant)
841 // Decompose the flat index into outer and inner indices using
842 // integer division and remainder. This is correct because
843 // multi-dimensional arrays are laid out contiguously, so
844 // flat_offset = k * const_factor maps to array[k / divider] at
845 // remaining offset (k % divider) * const_factor within that
846 // element. An inner index exceeding the inner dimension simply
847 // wraps to the next element, which is the correct flat-layout
884 // If the struct only has a single member then we recurse into that
886 const auto &components = ns.
follow_tag(*struct_tag_type).components();
887 if(components.size() == 1)
890 member_exprt{expr, components.front()}, offset, target_type, ns);
892 // If we have an offset C + x (where C is a constant) we can try to
893 // recurse by first looking at the member at offset C.
926 // For union-typed expressions with non-constant offset, access
927 // through the widest member to avoid expensive byte_extract lowering.
928 // This is safe when the widest member covers the full union (no
929 // trailing padding beyond it), since all members start at offset 0.
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.
bitvector_typet c_index_type()
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
A base class for relations, i.e., binary predicates whose two operands have the same type.
struct configt::ansi_ct ansi_c
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
bool is_constant() const
Return whether the expression is a constant.
typet & type()
Return the type of the expression.
The trinary if-then-else operator.
bool get_bool(const irep_idt &name) const
const irep_idt & id() const
Extract member of struct or union.
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Binary multiplication Associativity is not specified.
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...
Split an expression into a base object and a (byte) offset.
The plus expression Associativity is not specified.
Structure type, corresponds to C style structs.
const componentst & components() const
std::vector< componentt > componentst
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
API to expression classes for Pointers.
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.
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_bits(const typet &type, const namespacet &ns)
std::optional< mp_integer > member_offset_bits(const struct_typet &type, const irep_idt &member, const namespacet &ns)
bool is_zero_width(const typet &type, const namespacet &ns)
Returns true iff type has effective width of zero bits.
std::optional< mp_integer > compute_pointer_offset(const exprt &expr, const namespacet &ns)
static bool is_multiplication_by_constant(const exprt &expr)
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
std::optional< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
bool simplify(exprt &expr, const namespacet &ns)
exprt simplify_expr(exprt src, const namespacet &ns)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
bool is_ssa_expr(const exprt &expr)
const ssa_exprt & to_ssa_expr(const exprt &expr)
Cast a generic exprt to an ssa_exprt.
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
API to expression classes.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const mult_exprt & to_mult_expr(const exprt &expr)
Cast an exprt to a mult_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.