Commit 1937f939 by Jason Merrill Committed by Jason Merrill

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
parent 562349ca
2006-07-05 Jason Merrill <jason@redhat.com>
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 <mrs@apple.com> 2006-07-05 Mike Stump <mrs@apple.com>
* doc/invoke.texi (Invoking G++): Clarify prose for g++. * doc/invoke.texi (Invoking G++): Clarify prose for g++.
......
...@@ -4082,20 +4082,6 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args), ...@@ -4082,20 +4082,6 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
*node = build_variant_type_copy (*node); *node = build_variant_type_copy (*node);
TYPE_PACKED (*node) = 1; 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) else if (TREE_CODE (*node) == FIELD_DECL)
{ {
......
...@@ -5574,8 +5574,6 @@ finish_struct (tree t, tree fieldlist, tree attributes) ...@@ -5574,8 +5574,6 @@ finish_struct (tree t, tree fieldlist, tree attributes)
{ {
TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_FIELDS (x) = TYPE_FIELDS (t);
TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (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_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t); C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t); C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
......
2006-07-05 Jason Merrill <jason@redhat.com> 2006-07-05 Jason Merrill <jason@redhat.com>
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 PR c++/18681
* friend.c (is_friend): Fix DR 45 implementation. * friend.c (is_friend): Fix DR 45 implementation.
......
...@@ -1433,8 +1433,6 @@ finish_struct_bits (tree t) ...@@ -1433,8 +1433,6 @@ finish_struct_bits (tree t)
TYPE_VFIELD (variants) = TYPE_VFIELD (t); TYPE_VFIELD (variants) = TYPE_VFIELD (t);
TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_METHODS (variants) = TYPE_METHODS (t);
TYPE_FIELDS (variants) = TYPE_FIELDS (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)) if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
...@@ -2815,40 +2813,6 @@ check_field_decls (tree t, tree *access_decls, ...@@ -2815,40 +2813,6 @@ check_field_decls (tree t, tree *access_decls,
next = &TREE_CHAIN (x); 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) if (TREE_CODE (x) == USING_DECL)
{ {
/* Prune the access declaration from the list of fields. */ /* Prune the access declaration from the list of fields. */
...@@ -2945,6 +2909,34 @@ check_field_decls (tree t, tree *access_decls, ...@@ -2945,6 +2909,34 @@ check_field_decls (tree t, tree *access_decls,
type = strip_array_types (type); 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 /* This is used by -Weffc++ (see below). Warn only for pointers
to members which might hold dynamic memory. So do not warn to members which might hold dynamic memory. So do not warn
for pointers to functions or pointers to members. */ for pointers to functions or pointers to members. */
......
...@@ -1465,6 +1465,8 @@ finalize_type_size (tree type) ...@@ -1465,6 +1465,8 @@ finalize_type_size (tree type)
void void
finish_record_layout (record_layout_info rli, int free_p) finish_record_layout (record_layout_info rli, int free_p)
{ {
tree variant;
/* Compute the final size. */ /* Compute the final size. */
finalize_record_size (rli); finalize_record_size (rli);
...@@ -1474,6 +1476,12 @@ finish_record_layout (record_layout_info rli, int free_p) ...@@ -1474,6 +1476,12 @@ finish_record_layout (record_layout_info rli, int free_p)
/* Perform any last tweaks to the TYPE_SIZE, etc. */ /* Perform any last tweaks to the TYPE_SIZE, etc. */
finalize_type_size (rli->t); 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 /* Lay out any static members. This is done now because their type
may use the record's type. */ may use the record's type. */
while (rli->pending_statics) while (rli->pending_statics)
......
// PR c++/13983, c++/17519
// The typedef and the array were causing us to miss that A<int> is
// a packed type.
template <class T>
struct A {
A();
} __attribute__((packed));
typedef A<int> Ai;
struct B {
Ai a[2];
} __attribute__((packed));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment