From: Jason Merrill Date: Wed, 20 Jan 2010 22:14:51 +0000 (-0500) Subject: re PR c++/41788 (-Wpacked option changes the layout of packed non-POD structs) X-Git-Tag: releases/gcc-4.5.0~1121 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a402c1b130af88d5f5294dc977ec91dabbe6c388;p=thirdparty%2Fgcc.git re PR c++/41788 (-Wpacked option changes the layout of packed non-POD structs) PR c++/41788 * class.c (layout_class_type): Set packed_maybe_necessary for packed non-PODs. From-SVN: r156088 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 828f4b089a4b..4cc1119a211c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2010-01-20 Jason Merrill + 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. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 16d566682a6d..f88914d3c222 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 99c56149a4e8..a3bf6c99d4a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-01-20 Jason Merrill + 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 index 000000000000..4e759728a17d --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/packed1.C @@ -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 (); +}