re PR middle-end/27945 (Packed struct of variable length has wrong size)
authorJason Merrill <jason@redhat.com>
Tue, 11 Sep 2007 15:07:59 +0000 (11:07 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 11 Sep 2007 15:07:59 +0000 (11:07 -0400)
        PR middle-end/27945
        * stor-layout.c (layout_decl): Do pack variable size fields.

From-SVN: r128380

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/gcc.dg/packed-vla.c [new file with mode: 0644]

index add575350f5361505df8bffcc729d1b78db2e465..ac74a0e54c6e019368c4acb9bc9c04e516b2516e 100644 (file)
@@ -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,
index ea658a86aa0f85147b320c89b3aa95ce56a1ff7f..f149e68d537753bc1fba24205ef63a17c04aaf96 100644 (file)
@@ -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 (file)
index 0000000..d5fef5c
--- /dev/null
@@ -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;
+}