diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/stor-layout.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/packed-vla.c | 30 |
3 files changed, 39 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index add575350f5..ac74a0e54c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-09-11 Jason Merrill <jason@redhat.com> + + PR middle-end/27945 + * stor-layout.c (layout_decl): Do pack variable size fields. + 2007-09-11 Maxim Kuvyrkov <maxim@codesourcery.com> * config/m68k/predicates.md (movsi_const0_operand, diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index ea658a86aa0..f149e68d537 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -414,18 +414,11 @@ layout_decl (tree decl, unsigned int known_align) else do_type_align (type, decl); - /* If the field is of variable size, we can't misalign it since we - have no way to make a temporary to align the result. But this - isn't an issue if the decl is not addressable. Likewise if it - is of unknown size. - - Note that do_type_align may set DECL_USER_ALIGN, so we need to - check old_user_align instead. */ + /* If the field is packed and not explicitly aligned, give it the + minimum alignment. Note that do_type_align may set + DECL_USER_ALIGN, so we need to check old_user_align instead. */ if (packed_p - && !old_user_align - && (DECL_NONADDRESSABLE_P (decl) - || DECL_SIZE_UNIT (decl) == 0 - || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST)) + && !old_user_align) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); if (! packed_p && ! DECL_USER_ALIGN (decl)) diff --git a/gcc/testsuite/gcc.dg/packed-vla.c b/gcc/testsuite/gcc.dg/packed-vla.c new file mode 100644 index 00000000000..d5fef5c4ccf --- /dev/null +++ b/gcc/testsuite/gcc.dg/packed-vla.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "" } */ + +extern int printf (const char *, ...); +extern void abort (); + +int func(int levels) +{ + struct bar { + unsigned char a; + int b[levels]; + } __attribute__ ((__packed__)) bar; + + struct foo { + unsigned char a; + int b[4]; + } __attribute__ ((__packed__)) foo; + + printf("foo %d\n", sizeof(foo)); + printf("bar %d\n", sizeof(bar)); + + if (sizeof (foo) != sizeof (bar)) + abort (); +} + +int main() +{ + func(4); + return 0; +} |