From: Jason Merrill Date: Thu, 6 Jul 2006 02:09:02 +0000 (-0400) Subject: re PR c++/13983 (no warning on some non-POD struct with packed attribute) X-Git-Tag: releases/gcc-4.2.0~2178 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1937f93932b3249756fbeda05a0b0c67aaed0405;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. * c-common.c (handle_packed_attribute): So don't copy it here. * c-decl.c (finish_struct): Don't copy TYPE_ALIGN. * cp/class.c (check_field_decls): Check TYPE_PACKED after stripping array types. (finish_struct_bits): Don't copy TYPE_SIZE here. From-SVN: r115217 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a4d377bd4f3..fc4194d18e21 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2006-07-05 Jason Merrill + + PR c++/13983 + PR c++/17519 + * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants. + * c-common.c (handle_packed_attribute): So don't copy it here. + * c-decl.c (finish_struct): Don't copy TYPE_ALIGN. + 2006-07-05 Mike Stump * doc/invoke.texi (Invoking G++): Clarify prose for g++. diff --git a/gcc/c-common.c b/gcc/c-common.c index ac7dd7ddee3d..61bf12bbb59d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4082,20 +4082,6 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args), if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) *node = build_variant_type_copy (*node); TYPE_PACKED (*node) = 1; - if (TYPE_MAIN_VARIANT (*node) == *node) - { - /* If it is the main variant, then pack the other variants - too. This happens in, - - struct Foo { - struct Foo const *ptr; // creates a variant w/o packed flag - } __ attribute__((packed)); // packs it now. - */ - tree probe; - - for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe)) - TYPE_PACKED (probe) = 1; - } } else if (TREE_CODE (*node) == FIELD_DECL) { diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 250be0e055db..6ad6a695d089 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -5574,8 +5574,6 @@ finish_struct (tree t, tree fieldlist, tree attributes) { TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); - TYPE_ALIGN (x) = TYPE_ALIGN (t); - TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t); C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t); C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t); C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b1a1cbd1459d..3d3952cb681b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2006-07-05 Jason Merrill + PR c++/13983 + PR c++/17519 + * class.c (check_field_decls): Check TYPE_PACKED after + stripping array types. + (finish_struct_bits): Don't copy TYPE_SIZE here. + PR c++/18681 * friend.c (is_friend): Fix DR 45 implementation. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9761c5c41a7d..06f8cbceb533 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1433,8 +1433,6 @@ finish_struct_bits (tree t) TYPE_VFIELD (variants) = TYPE_VFIELD (t); TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t); - TYPE_SIZE (variants) = TYPE_SIZE (t); - TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t); } if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t)) @@ -2815,40 +2813,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))) - 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 - { - 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. */ @@ -2945,6 +2909,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 47bc6a047a73..76aa4ac73bbf 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1465,6 +1465,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); @@ -1474,6 +1476,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));