fix c/18282, for 4.0

Richard Henderson rth@redhat.com
Thu Dec 9 23:03:00 GMT 2004


This fixes the bug that Jakub spotted by which we would properly
parse the attribute when it was attached to a typedef, but not
when attached to a regular decl.

I've been thinking that I might port both patches back to 3.4,
since it has been pointed out that the mode attribute on a decl
appeared to function properly.  I say "appeared" because 

	enum B b __attribute__((mode(QI)));

was actually compiled to

	unsigned char b;

because we replaced the type node out from under the decl.  But
in C I'm not even sure how you'd notice the change to "char"
instead of another unique enum type.  Certainly you'd be able
to tell from the debugger, but that's grasping at straws.


r~


        * attribs.c (decl_attributes): Use relayout_decl.
        * c-common.c (handle_mode_attribute): Copy all relevant type
        parameters from the new underlying integral type.

Index: attribs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/attribs.c,v
retrieving revision 1.34
diff -c -p -d -r1.34 attribs.c
*** attribs.c	15 Sep 2004 20:47:35 -0000	1.34
--- attribs.c	9 Dec 2004 22:53:34 -0000
*************** decl_attributes (tree *node, tree attrib
*** 259,271 ****
  	  && (TREE_CODE (*node) == VAR_DECL
  	      || TREE_CODE (*node) == PARM_DECL
  	      || TREE_CODE (*node) == RESULT_DECL))
! 	{
! 	  /* Force a recalculation of mode and size.  */
! 	  DECL_MODE (*node) = VOIDmode;
! 	  DECL_SIZE (*node) = 0;
! 
! 	  layout_decl (*node, 0);
! 	}
  
        if (!no_add_attrs)
  	{
--- 259,265 ----
  	  && (TREE_CODE (*node) == VAR_DECL
  	      || TREE_CODE (*node) == PARM_DECL
  	      || TREE_CODE (*node) == RESULT_DECL))
! 	relayout_decl (*node);
  
        if (!no_add_attrs)
  	{
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.592
diff -c -p -d -r1.592 c-common.c
*** c-common.c	9 Dec 2004 22:52:15 -0000	1.592
--- c-common.c	9 Dec 2004 22:53:35 -0000
*************** handle_mode_attribute (tree *node, tree 
*** 4302,4308 ****
--- 4302,4318 ----
  
  	  if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
  	    type = build_variant_type_copy (type);
+ 
+ 	  /* We cannot use layout_type here, because that will attempt
+ 	     to re-layout all variants, corrupting our original.  */
  	  TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+ 	  TYPE_MIN_VALUE (type) = TYPE_MIN_VALUE (typefm);
+ 	  TYPE_MAX_VALUE (type) = TYPE_MAX_VALUE (typefm);
+ 	  TYPE_SIZE (type) = TYPE_SIZE (typefm);
+ 	  TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (typefm);
+ 	  if (!TYPE_USER_ALIGN (type))
+ 	    TYPE_ALIGN (type) = TYPE_ALIGN (typefm);
+ 
  	  typefm = type;
  	}
        else if (VECTOR_MODE_P (mode)
*************** handle_mode_attribute (tree *node, tree 
*** 4314,4321 ****
  	}
  
        *node = typefm;
- 
-       /* No need to layout the type here.  The caller should do this.  */
      }
  
    return NULL_TREE;
--- 4324,4329 ----



More information about the Gcc-patches mailing list