1/*******************************************************************\
3Module: C++ Language Type Checking
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
25 // we need to consider a number of different cases:
26 // - alignment specified in the source, which will be recorded in
28 // - alignment induced by packing ("The alignment of a member will
29 // be on a boundary that is either a multiple of n or a multiple of
30 // the size of the member, whichever is smaller."); both
31 // ID_C_alignment and ID_C_packed will be set
32 // - natural alignment, when neither ID_C_alignment nor ID_C_packed
34 // - dense packing with only ID_C_packed set.
36 // is the alignment given?
42 // we trust it blindly, no matter how nonsensical
50 // alignment but no packing
53 // no alignment, packing
67 // (should really be the smallest common denominator)
69 result = std::max(result,
alignment(
c.type(), ns));
90 // we align these according to the 'underlying type'
96 // if an alignment had been provided and packing was requested, take
97 // the smallest alignment
104static std::optional<std::size_t>
111 // This is the 'proper' bool.
122 // These point to an enum, which has a sub-subtype,
123 // which may be smaller or larger than int, and we thus have
139 struct_typet::componentst::iterator where,
146 "$bit_field_pad" + std::to_string(where - components.begin()),
151 return std::next(components.insert(where,
component));
154 static struct_typet::componentst::iterator
pad(
156 struct_typet::componentst::iterator where,
162 "$pad" + std::to_string(where - components.begin()),
167 return std::next(components.insert(where,
component));
179 for(struct_typet::componentst::iterator it = components.begin();
180 it != components.end();
183 // there is exactly one case in which padding is not added:
184 // if we continue a bit-field with size>0 and the same underlying width
192 // do not add padding, but count the bits
202 // pad up any remaining bit field
217 // pad up to underlying type unless the struct is packed
236 // do we start a new bit field?
244 else if(it->is_boolean())
251 // keep track of offset
253 if(size.has_value() && *size >= 1)
259 // Add padding at the end?
263 const std::size_t
pad =
271 // alignment of the struct
272 // Note that this is done even if the struct is packed.
290 // First make bit-fields appear on byte boundaries
294 for(struct_typet::componentst::iterator
295 it=components.begin();
296 it!=components.end();
306 else if(it->is_boolean())
312 // not on a byte-boundary?
324 // Add padding at the end?
327 const std::size_t
pad =
338 for(struct_typet::componentst::iterator
339 it=components.begin();
340 it!=components.end();
350 // A zero-width bit-field causes alignment to the base-type.
356 // Otherwise, ANSI-C says that bit-fields do not get padded!
357 // We consider the type for max_alignment, however.
385 bit_field_bits == 0,
"padding ensures offset at byte boundaries");
387 // check minimum alignment
405 // we may need to align it
424 // any explicit alignment for the struct?
437 // Is the struct packed, without any alignment specification?
441 // There may be a need for 'end of struct' padding.
442 // We use 'max_alignment'.
446 // we may need to align it
461 // padding depends greatly on compiler
474 // check per component, and ignore those without fixed size
482 // Is the union packed?
485 // The size needs to be a multiple of 1 char only.
491 // Visual Studio pads up to the underlying width of
502 // The size must be a multiple of the alignment, or
503 // we add a padding member to the union.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
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_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...
Type for C bit fields These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (...
const typet & underlying_type() const
struct configt::ansi_ct ansi_c
Base class for all expressions.
bool get_bool(const irep_idt &name) const
const irept & find(const irep_idt &name) const
const irep_idt & id() const
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...
Structure type, corresponds to C style structs.
const componentst & components() const
std::vector< componentt > componentst
The type of an expression, extends irept.
Fixed-width bit-vector with unsigned binary interpretation.
static std::optional< std::size_t > underlying_width(const c_bit_field_typet &type, const namespacet &ns)
mp_integer alignment(const typet &type, const namespacet &ns)
static void add_padding_msvc(struct_typet &type, const namespacet &ns)
static void add_padding_gcc(struct_typet &type, const namespacet &ns)
void add_padding(struct_typet &type, const namespacet &ns)
static struct_typet::componentst::iterator pad(struct_typet::componentst &components, struct_typet::componentst::iterator where, std::size_t pad_bits)
static struct_typet::componentst::iterator pad_bit_field(struct_typet::componentst &components, struct_typet::componentst::iterator where, std::size_t pad_bits)
ANSI-C Language Type Checking.
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< mp_integer > pointer_offset_bits(const typet &type, 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,...
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_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.