This is the mail archive of the 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] Partial mode enumerals in signed_or_unsigned_type

The following patch is a variation on one proposed by Mark Mitchell
to address the C++ aspects of PR 15069.  Currently when the middle-end
asks for a signed or unsigned variant of an enumerated type, its
possible for the current C-family lang_hooks to return a type with
a different width (TYPE_PRECISION).  This was diagnosed by RTH as a
front-end bug:

Mark's proposed solution (which is attached to PR 15069 in bugzilla)
was for the C++ front-end to provide its own langhook implementations
for signed_type, unsigned_type and signed_or_unsigned_type, which wrap
the generic c-family implementations intercepting the problematic
cases.  My minor contribution below is to suggest that this special
case handling could be placed in c_common_signed_or_unsigned_type.
It turns out that the generic signed_type and unsigned_type hooks
filter down to this single function.  This leads to a much shorter
patch, with changes/maintenance restricted to a single function,
which should also avoid problems in C and/or Objective-C should they
ever encounter a partial mode enumerated type.

Although PR 15069 has since been addressed on both mainline and the
gcc-3_4-branch, this patch starts the process of fixing the latent
C++ and tree-ssa bugs that investigating it exposed.

The following patch has been tested on i686-pc-linux-gnu with a
complete "make bootstrap", all default languages, and regression
tested with a top-level "make -k check" with no new failures.

Ok for mainline?  If not, would Mark's C++-only fix be preferred?

2004-06-01  Roger Sayle  <>
	    Mark Mitchell  <>

	* c-common.c (c_common_signed_or_unsigned_type):  Maintain signed
	and unsigned versions of enumeral types as variants of each other.

Index: c-common.c
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.509
diff -c -3 -p -r1.509 c-common.c
*** c-common.c	30 May 2004 23:53:25 -0000	1.509
--- c-common.c	1 Jun 2004 03:58:38 -0000
*************** c_common_signed_or_unsigned_type (int un
*** 2032,2037 ****
--- 2032,2056 ----
        || TYPE_UNSIGNED (type) == unsignedp)
      return type;

+   /* Handle enumerations that are narrower than their modes specially.  */
+   if (TREE_CODE (type) == ENUMERAL_TYPE
+       && TYPE_PRECISION (type) != GET_MODE_BITSIZE (TYPE_MODE (type)))
+     {
+       tree v;
+       /* See if we already have this variant.  */
+       for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v))
+ 	{
+ 	  tree t = TREE_CODE (v) == TYPE_DECL ? TREE_TYPE (v) : v;
+ 	  if (TYPE_UNSIGNED (t) == unsignedp)
+ 	    return t;
+ 	}
+       v = build_type_copy (type);
+       TYPE_UNSIGNED (v) = unsignedp;
+       return v;
+     }
    /* Must check the mode of the types, not the precision.  Enumeral types
       in C++ have precision set to match their range, but may use a wider
       mode to match an ABI.  If we change modes, we may wind up with bad

Roger Sayle,                         E-mail:
OpenEye Scientific Software,         WWW:
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

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