From: Jason Merrill Date: Thu, 6 Jul 2006 03:33:20 +0000 (-0400) Subject: re PR c++/13983 (no warning on some non-POD struct with packed attribute) X-Git-Tag: releases/gcc-4.0.4~554 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11262a0553bd4912f1712a0a234aa9d622ed4f7e;p=thirdparty%2Fgcc.git re PR c++/13983 (no warning on some non-POD struct with packed attribute) PR c++/13983 PR c++/17519 * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants. * cp/class.c (check_field_decls): Check TYPE_PACKED after stripping array types. From-SVN: r115220 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1aeae105526..3a118e4fa763 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-07-05 Jason Merrill + + PR c++/13983 + PR c++/17519 + * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants. + 2006-07-04 Peter O'Gorman * mklibgcc.in: chmod 644 before ranlib during install. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 417266192695..2c88746868e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2006-07-05 Jason Merrill + + PR c++/13983 + PR c++/17519 + * class.c (check_field_decls): Check TYPE_PACKED after + stripping array types. + +2006-07-05 Nathan Sidwell + + PR c++/21166 + * class.c (check_field_decls): Only set DECL_PACKED on a field + when its natural alignment is > BITS_PER_UNIT. + 2006-07-05 Jason Merrill PR c++/18681 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 14e8728ca8e9..8066ec9f7fbd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2850,39 +2850,6 @@ check_field_decls (tree t, tree *access_decls, next = &TREE_CHAIN (x); - if (TREE_CODE (x) == FIELD_DECL) - { - if (TYPE_PACKED (t)) - { - if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x))) - cp_warning_at - ("ignoring packed attribute on unpacked non-POD field %q#D", - x); - else - DECL_PACKED (x) = 1; - } - - if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) - /* We don't treat zero-width bitfields as making a class - non-empty. */ - ; - else - { - tree element_type; - - /* The class is non-empty. */ - CLASSTYPE_EMPTY_P (t) = 0; - /* The class is not even nearly empty. */ - CLASSTYPE_NEARLY_EMPTY_P (t) = 0; - /* If one of the data members contains an empty class, - so does T. */ - element_type = strip_array_types (type); - if (CLASS_TYPE_P (element_type) - && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)) - CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; - } - } - if (TREE_CODE (x) == USING_DECL) { /* Prune the access declaration from the list of fields. */ @@ -2979,6 +2946,34 @@ check_field_decls (tree t, tree *access_decls, type = strip_array_types (type); + if (TYPE_PACKED (t)) + { + if (!pod_type_p (type) && !TYPE_PACKED (type)) + warning + (0, + "ignoring packed attribute on unpacked non-POD field %q+#D", + x); + else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) + DECL_PACKED (x) = 1; + } + + if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) + /* We don't treat zero-width bitfields as making a class + non-empty. */ + ; + else + { + /* The class is non-empty. */ + CLASSTYPE_EMPTY_P (t) = 0; + /* The class is not even nearly empty. */ + CLASSTYPE_NEARLY_EMPTY_P (t) = 0; + /* If one of the data members contains an empty class, + so does T. */ + if (CLASS_TYPE_P (type) + && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type)) + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; + } + /* This is used by -Weffc++ (see below). Warn only for pointers to members which might hold dynamic memory. So do not warn for pointers to functions or pointers to members. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 44aeea826abb..78295c5f6f94 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1418,6 +1418,8 @@ finalize_type_size (tree type) void finish_record_layout (record_layout_info rli, int free_p) { + tree variant; + /* Compute the final size. */ finalize_record_size (rli); @@ -1427,6 +1429,12 @@ finish_record_layout (record_layout_info rli, int free_p) /* Perform any last tweaks to the TYPE_SIZE, etc. */ finalize_type_size (rli->t); + /* Propagate TYPE_PACKED to variants. With C++ templates, + handle_packed_attribute is too early to do this. */ + for (variant = TYPE_NEXT_VARIANT (rli->t); variant; + variant = TYPE_NEXT_VARIANT (variant)) + TYPE_PACKED (variant) = TYPE_PACKED (rli->t); + /* Lay out any static members. This is done now because their type may use the record's type. */ while (rli->pending_statics) diff --git a/gcc/testsuite/g++.dg/ext/packed10.C b/gcc/testsuite/g++.dg/ext/packed10.C new file mode 100644 index 000000000000..c4bbb1462d99 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed10.C @@ -0,0 +1,14 @@ +// PR c++/13983, c++/17519 +// The typedef and the array were causing us to miss that A is +// a packed type. + +template +struct A { + A(); +} __attribute__((packed)); + +typedef A Ai; + +struct B { + Ai a[2]; +} __attribute__((packed));