OSDN Git Service

* c-common.c (handle_packed_attribute): Don't pack a struct via a
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jul 2003 09:26:01 +0000 (09:26 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jul 2003 09:26:01 +0000 (09:26 +0000)
typedef. Propagate packedness from a main variant.
testsuite:
* gcc.dg/pack-test-3.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69668 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pack-test-3.c [new file with mode: 0644]

index 0db1664..85eab61 100644 (file)
@@ -1,3 +1,8 @@
+2003-07-16  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * c-common.c (handle_packed_attribute): Don't pack a struct via a
+       typedef. Propagate packedness from a main variant.
+
 2003-07-22  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        * Makefile.in (install-common): Add dependency on installdirs.
index c33e632..b5d6651 100644 (file)
@@ -4534,25 +4534,33 @@ static tree
 handle_packed_attribute (tree *node, tree name, tree args  ATTRIBUTE_UNUSED,
                         int flags, bool *no_add_attrs)
 {
-  tree *type = NULL;
-  if (DECL_P (*node))
-    {
-      if (TREE_CODE (*node) == TYPE_DECL)
-       type = &TREE_TYPE (*node);
-    }
-  else
-    type = node;
-
-  if (type)
+  if (TYPE_P (*node))
     {
       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
-       *type = build_type_copy (*type);
-      TYPE_PACKED (*type) = 1;
+       *node = build_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)
     DECL_PACKED (*node) = 1;
   /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
-     used for DECL_REGISTER.  It wouldn't mean anything anyway.  */
+     used for DECL_REGISTER.  It wouldn't mean anything anyway.
+     We can't set DECL_PACKED on the type of a TYPE_DECL, because
+     that changes what the typedef is typing.  */
   else
     {
       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
index ec60181..25fd059 100644 (file)
@@ -1,3 +1,7 @@
+2003-07-22  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * gcc.dg/pack-test-3.c: New test.
+
 2003-07-21  Janis Johnson  <janis187@us.ibm.com>
 
        * lib/compat.exp: Handle dg-options per source file.
diff --git a/gcc/testsuite/gcc.dg/pack-test-3.c b/gcc/testsuite/gcc.dg/pack-test-3.c
new file mode 100644 (file)
index 0000000..8b03903
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com> */
+
+/* you should not be able to pack a typedef to a struct, only the
+   underlying struct can be packed.  */
+
+/* ok */
+struct u1
+{
+  char field1;
+  short field2;
+  int field3;
+};
+
+/* ok */
+typedef struct p1 {
+   char  field1;
+   short field2;
+   int field3;
+} __attribute__ ((packed)) p1_t1;
+
+/* ok */
+typedef struct __attribute__ ((packed)) p2 {
+   char  field1;
+   short field2;
+   int field3;
+} p2_t1;
+
+int ary1[sizeof (struct p1) == sizeof (p1_t1) ? 1 : -1];
+int ary2[sizeof (struct p2) == sizeof (p2_t1) ? 1 : -1];
+int ary3[sizeof (struct p1) == sizeof (struct p2) ? 1 : -1];
+
+/* not ok */
+typedef struct u1 __attribute__ ((packed)) u1_t1; /* { dg-warning "attribute ignored" "" }*/
+typedef struct u1 u1_t2 __attribute__ ((packed)); /* { dg-warning "attribute ignored" "" }*/
+
+typedef struct p3 {
+   char  field1;
+   short field2;
+   int field3;
+} p3_t1 __attribute__ ((packed)); /* { dg-warning "attribute ignored" "" }*/
+