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]

Proposed fix for PR c/15224


I want to run this by some C-front-end folks.  It looks right to me and
tests OK on x86-64-linux-gnu.

2004-08-31  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	PR c/15224
	* c-common.c (handle_mode_attribute): Handle ENUMERAL_TYPE.
	* c-decl.c (finish_enum): Check for user-specified precision too small.

*** c-common.c	28 Aug 2004 02:33:45 -0000	1.562
--- c-common.c	29 Aug 2004 21:32:32 -0000
*************** handle_mode_attribute (tree *node, tree 
*** 4352,4355 ****
--- 4352,4356 ----
        else
          typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
+ 
        if (typefm == NULL_TREE)
  	{
*************** handle_mode_attribute (tree *node, tree 
*** 4357,4360 ****
--- 4358,4378 ----
  	  return NULL_TREE;
  	}
+       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",
+ 		     GET_MODE_NAME (mode));
+ 	      return NULL_TREE;
+ 	    }
+ 
+ 	  if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ 	    type = build_variant_type_copy (type);
+ 	  TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+ 	  typefm = type;
+ 	}
        *node = typefm;
  
*** c-decl.c	26 Aug 2004 21:30:15 -0000	1.564
--- c-decl.c	29 Aug 2004 21:32:37 -0000
*************** finish_enum (tree enumtype, tree values,
*** 5675,5678 ****
--- 5675,5679 ----
    precision = MAX (min_precision (minnode, unsign),
  		   min_precision (maxnode, unsign));
+ 
    if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
      {
*************** finish_enum (tree enumtype, tree values,
*** 5689,5695 ****
    TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
    TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
-   TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
    TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
    TYPE_SIZE (enumtype) = 0;
    layout_type (enumtype);
  
--- 5690,5706 ----
    TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
    TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
    TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
    TYPE_SIZE (enumtype) = 0;
+ 
+   /* If the precision of the type was specific with an attribute and it
+      was too small, give an error.  Otherwise, use it.  */
+   if (TYPE_PRECISION (enumtype))
+     {
+       if (precision > TYPE_PRECISION (enumtype))
+ 	error ("specified mode too small for enumeral values");
+     }
+   else
+     TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
+ 
    layout_type (enumtype);
  


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