aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2006-07-05 22:09:02 -0400
committerJason Merrill <jason@gcc.gnu.org>2006-07-05 22:09:02 -0400
commit1937f93932b3249756fbeda05a0b0c67aaed0405 (patch)
treee5a04b6dd5dab15766d0b02b4b48425818534909 /gcc
parent562349cab017b2abc827517378ac50a1f4a1f438 (diff)
downloadgcc-1937f93932b3249756fbeda05a0b0c67aaed0405.zip
gcc-1937f93932b3249756fbeda05a0b0c67aaed0405.tar.gz
gcc-1937f93932b3249756fbeda05a0b0c67aaed0405.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-common.c14
-rw-r--r--gcc/c-decl.c2
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c64
-rw-r--r--gcc/stor-layout.c8
-rw-r--r--gcc/testsuite/g++.dg/ext/packed10.C14
7 files changed, 64 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a4d377..fc4194d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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>
* doc/invoke.texi (Invoking G++): Clarify prose for g++.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index ac7dd7d..61bf12b 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 250be0e..6ad6a69 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 b1a1cbd..3d3952c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
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
* friend.c (is_friend): Fix DR 45 implementation.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 9761c5c..06f8cbc 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 47bc6a0..76aa4ac 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 0000000..c4bbb14
--- /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<int> is
+// a packed type.
+
+template <class T>
+struct A {
+ A();
+} __attribute__((packed));
+
+typedef A<int> Ai;
+
+struct B {
+ Ai a[2];
+} __attribute__((packed));