This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Don't pack a typedef of a struct


hi,
this patch stops you trying to apply a packed attribute to a typedef
of a struct - only the underlying struct can be packed.

I also discovered that when you do pack a struct by placing the packed
attribute after the closing '}', any variants of that struct will
not have a packed flag set. There is no test case for that, but a C++ patch
& test I'm about to provide will test that functionality.

booted & tested on i686-pc-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2003-07-16  Nathan Sidwell  <nathan@codesourcery.com>

	* handle_packed_attribute: Don't pack a struct via a
	typedef. Propagate packedness from a main variant.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.429
diff -c -3 -p -r1.429 c-common.c
*** c-common.c	15 Jul 2003 05:44:29 -0000	1.429
--- c-common.c	16 Jul 2003 08:55:41 -0000
*************** static tree
*** 4536,4560 ****
  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 (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	*type = build_type_copy (*type);
!       TYPE_PACKED (*type) = 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.  */
    else
      {
        warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
--- 4536,4568 ----
  handle_packed_attribute (tree *node, tree name, tree args  ATTRIBUTE_UNUSED,
  			 int flags, bool *no_add_attrs)
  {
!   if (TYPE_P (*node))
      {
        if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	*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.
!      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));
/* { 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)];
int ary2[sizeof (struct p2) == sizeof (p2_t1)];
int ary3[sizeof (struct p1) == sizeof (struct p2)];

/* 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" "" }*/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]