diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-10-05 17:58:28 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-12-29 14:44:21 +0100 |
commit | 2cf493d1f63f075e6fe0cccbcb7463b1aa773a74 (patch) | |
tree | a673b2a8ad549a2631936ef54d141731859dc2e3 | |
parent | f07a1053a90039a2d88ed62f74add2ee131d67b7 (diff) | |
download | sparse-2cf493d1f63f075e6fe0cccbcb7463b1aa773a74.tar.gz |
packed: add support for __packed struct
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>
-rw-r--r-- | Documentation/TODO.md | 3 | ||||
-rw-r--r-- | parse.c | 5 | ||||
-rw-r--r-- | symbol.c | 12 | ||||
-rw-r--r-- | symbol.h | 1 | ||||
-rw-r--r-- | validation/packed-bitfield0.c | 1 | ||||
-rw-r--r-- | validation/packed-bitfield1.c | 1 | ||||
-rw-r--r-- | validation/packed-bitfield2.c | 1 | ||||
-rw-r--r-- | validation/packed-bitfield5.c | 1 | ||||
-rw-r--r-- | validation/packed-deref0.c | 1 | ||||
-rw-r--r-- | validation/packed-struct.c | 1 |
10 files changed, 14 insertions, 13 deletions
diff --git a/Documentation/TODO.md b/Documentation/TODO.md index 4dc9e63a..3f00bb11 100644 --- a/Documentation/TODO.md +++ b/Documentation/TODO.md @@ -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; diff --git a/validation/packed-bitfield0.c b/validation/packed-bitfield0.c index f84e7b90..2e209161 100644 --- a/validation/packed-bitfield0.c +++ b/validation/packed-bitfield0.c @@ -55,5 +55,4 @@ int main(void) /* * check-name: packed-bitfield0 - * check-known-to-fail */ diff --git a/validation/packed-bitfield1.c b/validation/packed-bitfield1.c index 208a3dc5..b7b575ce 100644 --- a/validation/packed-bitfield1.c +++ b/validation/packed-bitfield1.c @@ -24,5 +24,4 @@ static int foo(struct s *ptr) /* * check-name: packed-bitfield1 - * check-known-to-fail */ diff --git a/validation/packed-bitfield2.c b/validation/packed-bitfield2.c index 4587ebec..244204c2 100644 --- a/validation/packed-bitfield2.c +++ b/validation/packed-bitfield2.c @@ -12,5 +12,4 @@ _Static_assert(sizeof(struct bf2) == 8); /* * check-name: packed-bitfield2 - * check-known-to-fail */ diff --git a/validation/packed-bitfield5.c b/validation/packed-bitfield5.c index 8f44d4c2..87dbf9c2 100644 --- a/validation/packed-bitfield5.c +++ b/validation/packed-bitfield5.c @@ -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 */ diff --git a/validation/packed-deref0.c b/validation/packed-deref0.c index 865ad68a..d48ad1ac 100644 --- a/validation/packed-deref0.c +++ b/validation/packed-deref0.c @@ -20,5 +20,4 @@ static void bar(obj_t o) /* * check-name: packed-deref0 - * check-known-to-fail */ diff --git a/validation/packed-struct.c b/validation/packed-struct.c index e21d1153..dad22791 100644 --- a/validation/packed-struct.c +++ b/validation/packed-struct.c @@ -29,5 +29,4 @@ _Static_assert( sizeof(struct c) == 6, "size struct"); /* * check-name: packed-struct - * check-known-to-fail */ |