This is the mail archive of the gcc@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]

Re: Mode for enum rejected on 3.4 branch


On Sat, Oct 16, 2004 at 08:26:19PM +0200, Volker Reichelt wrote:
> > The only way to make this work is to backport more code from
> > mainline:
> 
> Are you going to do so?

Apparently not, since it's not as easy as that.

> One could argue that the behavior on the 3.4 branch is a regression,
> since gcc always used to accept the code (even if this caused
> wrong-code) and now it is rejected without being invalid (it's
> accepted on mainline).

No, the only reasonable argument is that this is a new feature for 4.0.
It did not work in any previous gcc version, so no user could possibly
be relying on the feature.

If you'd like to play with this yourself, here's a prototype patch that
works for C, but not for C++.

Test case is

  typedef enum { A = 1 } __attribute__((mode(HI))) E1;
  E1 e1;
  enum { B = 1 } __attribute__((mode(HI))) e2;

  extern char compile_time_assert1[sizeof(e1) == 2 ? 1 : -1];
  extern char compile_time_assert2[sizeof(e2) == 2 ? 1 : -1];
  



r~



Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.476.4.9
diff -c -p -d -r1.476.4.9 c-common.c
*** c-common.c	13 Oct 2004 23:29:04 -0000	1.476.4.9
--- c-common.c	18 Oct 2004 21:06:11 -0000
*************** handle_mode_attribute (tree *node, tree 
*** 4678,4683 ****
--- 4678,4702 ----
  							mode);
  	      *node = ptr_type;
  	    }
+ 	  else if (TREE_CODE (type) == ENUMERAL_TYPE)
+ 	    {
+ 	      /* For enumeral types, copy the precision from the integer
+ 		 type returned above.  If not an INTEGER_TYPE, we can't use
+ 		 this mode for this type.  */
+ 	      if (TREE_CODE (typefm) != INTEGER_TYPE)
+ 		{
+ 		  error ("cannot use mode `%s' for enumeral types", p);
+ 		  return NULL_TREE;
+ 		}
+  
+ 	      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ 		type = build_type_copy (type);
+ 	      TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+ 	      TYPE_MODE (type) = VOIDmode;
+ 	      TYPE_SIZE (type) = NULL;
+ 
+ 	      *node = type;
+ 	    }
  	  else if (VECTOR_MODE_P (mode)
  		   ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
  		   : TREE_CODE (type) != TREE_CODE (typefm))
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.470.4.16
diff -c -p -d -r1.470.4.16 c-decl.c
*** c-decl.c	17 Aug 2004 16:24:57 -0000	1.470.4.16
--- c-decl.c	18 Oct 2004 21:06:11 -0000
*************** finish_enum (tree enumtype, tree values,
*** 5263,5269 ****
    unsign = (tree_int_cst_sgn (minnode) >= 0);
    precision = MAX (min_precision (minnode, unsign),
  		   min_precision (maxnode, unsign));
!   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
      {
        tree narrowest = c_common_type_for_size (precision, unsign);
        if (narrowest == 0)
--- 5263,5279 ----
    unsign = (tree_int_cst_sgn (minnode) >= 0);
    precision = MAX (min_precision (minnode, unsign),
  		   min_precision (maxnode, unsign));
! 
!   /* If the user selected a precision with a mode attribute, use it.
!      If the mode was too small, give an error.  */
!   if (TYPE_PRECISION (enumtype) > 0)
!     {
!       if (precision > TYPE_PRECISION (enumtype))
! 	error ("specified mode too small for enumeral values");
!       precision = TYPE_PRECISION (enumtype);
!     }
!   else if (TYPE_PACKED (enumtype)
! 	   || precision > TYPE_PRECISION (integer_type_node))
      {
        tree narrowest = c_common_type_for_size (precision, unsign);
        if (narrowest == 0)


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