@@ -4,9 +4,6 @@ TODO
Essential
---------
* SSA is broken by simplify_loads() & branches rewriting/simplification
-* attributes of struct, union & enums are ignored (and maybe others too).
- This requires correct support for __packed which itself needs partial
- and unaligned loads & stores (wip)
* add support for bitwise enums (wip)
Documentation
@@ -767,6 +767,7 @@ static struct token *struct_union_enum_specifier(enum type type,
attr.ctype.base_type = sym;
token = handle_attributes(token, &attr);
apply_ctype(token->pos, &sym->ctype, &attr.ctype);
+ sym->packed = attr.packed;
sym->endpos = token->pos;
@@ -1089,8 +1090,10 @@ static struct token *ignore_attribute(struct token *token, struct symbol *attr,
static struct token *attribute_packed(struct token *token, struct symbol *attr, struct decl_state *ctx)
{
- if (!ctx->ctype.alignment)
+ if (!ctx->ctype.alignment) {
ctx->ctype.alignment = 1;
+ ctx->packed = 1;
+ }
return token;
}
@@ -88,6 +88,7 @@ struct struct_union_info {
unsigned long bit_size;
int align_size;
char has_flex_array;
+ bool packed;
struct symbol *flex_array;
};
@@ -120,6 +121,7 @@ static int bitfield_base_size(struct symbol *sym)
static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
{
unsigned long bit_size, align_bit_mask;
+ unsigned long alignment;
int base_size;
bit_size = info->bit_size;
@@ -136,7 +138,8 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
info->flex_array = sym;
}
- align_bit_mask = bytes_to_bits(sym->ctype.alignment) - 1;
+ alignment = info->packed ? 1 : sym->ctype.alignment;
+ align_bit_mask = bytes_to_bits(alignment) - 1;
/*
* Bitfields have some very special rules..
@@ -147,7 +150,7 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
// Zero-width fields just fill up the unit.
int width = base_size ? : (bit_offset ? room : 0);
- if (width > room) {
+ if (width > room && !info->packed) {
bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
bit_offset = 0;
}
@@ -157,6 +160,8 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
info->bit_size = bit_size + width;
// warning (sym->pos, "bitfield: offset=%d:%d size=:%d", sym->offset, sym->bit_offset, width);
+ if (info->packed && sym->type == SYM_NODE)
+ sym->packed = 1;
return;
}
@@ -173,6 +178,7 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
static struct symbol * examine_struct_union_type(struct symbol *sym, int advance)
{
struct struct_union_info info = {
+ .packed = sym->packed,
.max_align = 1,
.bit_size = 0,
.align_size = 1
@@ -191,7 +197,7 @@ static struct symbol * examine_struct_union_type(struct symbol *sym, int advance
sparse_error(info.flex_array->pos, "flexible array member '%s' is not last", show_ident(info.flex_array->ident));
examine_symbol_type(member);
- if (member->ctype.alignment > info.max_align) {
+ if (member->ctype.alignment > info.max_align && !sym->packed) {
// Unnamed bitfields do not affect alignment.
if (member->ident || !is_bitfield_type(member))
info.max_align = member->ctype.alignment;
@@ -112,6 +112,7 @@ struct decl_state {
unsigned char prefer_abstract;
unsigned char autotype;
unsigned char forced;
+ unsigned char packed;
};
struct pseudo;
@@ -55,5 +55,4 @@ int main(void)
/*
* check-name: packed-bitfield0
- * check-known-to-fail
*/
@@ -24,5 +24,4 @@ static int foo(struct s *ptr)
/*
* check-name: packed-bitfield1
- * check-known-to-fail
*/
@@ -12,5 +12,4 @@ _Static_assert(sizeof(struct bf2) == 8);
/*
* check-name: packed-bitfield2
- * check-known-to-fail
*/
@@ -17,5 +17,4 @@ static int ld(struct s *s)
/*
* check-name: packed-bitfield5
* check-description: is check_access() OK with 'overlapping' packed bitfields?
- * check-known-to-fail
*/
@@ -20,5 +20,4 @@ static void bar(obj_t o)
/*
* check-name: packed-deref0
- * check-known-to-fail
*/
@@ -29,5 +29,4 @@ _Static_assert( sizeof(struct c) == 6, "size struct");
/*
* check-name: packed-struct
- * check-known-to-fail
*/
Now that the 'packed' attribute is parsed and propagated into the type system, adapt the layout of structures. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- Documentation/TODO.md | 3 --- parse.c | 5 ++++- symbol.c | 12 +++++++++--- symbol.h | 1 + validation/packed-bitfield0.c | 1 - validation/packed-bitfield1.c | 1 - validation/packed-bitfield2.c | 1 - validation/packed-bitfield5.c | 1 - validation/packed-deref0.c | 1 - validation/packed-struct.c | 1 - 10 files changed, 14 insertions(+), 13 deletions(-)