OSDN Git Service

PR c++/41788
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 22:14:51 +0000 (22:14 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 22:14:51 +0000 (22:14 +0000)
* class.c (layout_class_type): Set packed_maybe_necessary for packed
non-PODs.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156088 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/packed1.C [new file with mode: 0644]

index 828f4b0..4cc1119 100644 (file)
@@ -1,5 +1,9 @@
 2010-01-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/41788
+       * class.c (layout_class_type): Set packed_maybe_necessary for packed
+       non-PODs.
+
        PR c++/41920
        * semantics.c (build_lambda_object): Call mark_used on captured
        variables.
index 16d5666..f88914d 100644 (file)
@@ -5216,6 +5216,11 @@ layout_class_type (tree t, tree *virtuals_p)
                 build_decl (input_location,
                             FIELD_DECL, NULL_TREE, char_type_node));
 
+  /* If this is a non-POD, declaring it packed makes a difference to how it
+     can be used as a field; don't let finalize_record_size undo it.  */
+  if (TYPE_PACKED (t) && !layout_pod_type_p (t))
+    rli->packed_maybe_necessary = true;
+
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
index 99c5614..a3bf6c9 100644 (file)
@@ -1,5 +1,8 @@
 2010-01-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/41788
+       * g++.dg/abi/packed1.C: New.
+
        PR c++/41920
        * g++.dg/cpp0x/lambda/lambda-warn1.C: New.
 
diff --git a/gcc/testsuite/g++.dg/abi/packed1.C b/gcc/testsuite/g++.dg/abi/packed1.C
new file mode 100644 (file)
index 0000000..4e75972
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/41788
+// { dg-options "-Wpacked" }
+// { dg-do run }
+
+extern "C" void abort ();
+
+struct INNER {
+  virtual int foo() const { return 1; }
+} __attribute__ ((packed));
+
+struct OUTER {
+  char c;
+  INNER inner;
+} __attribute__ ((packed));
+
+int main()
+{
+  OUTER outer;
+  int s = sizeof(outer);
+  int o = (char *)&outer.inner - (char *)&outer;
+  if (s != sizeof (char) + sizeof (void*)
+      || o != sizeof (char))
+    abort ();
+}