c-decl.c (finish_enum): Convert enumerations that fit in an `int' to `int'.
authorAlexandre Oliva <aoliva@redhat.com>
Wed, 26 Jul 2000 03:50:56 +0000 (03:50 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Wed, 26 Jul 2000 03:50:56 +0000 (03:50 +0000)
* c-decl.c (finish_enum): Convert enumerations that fit in an
`int' to `int'.
(build_enumerator): In pedantic mode, cast to `int' those that
don't.

From-SVN: r35259

gcc/ChangeLog
gcc/c-decl.c

index b5955a54e555e429c1dd74847a8b734398803e93..52399578e99212b0a93d181b58b8fdb42f162047 100644 (file)
@@ -1,3 +1,10 @@
+2000-07-26  Alexandre Oliva  <aoliva@redhat.com>
+
+       * c-decl.c (finish_enum): Convert enumerations that fit in an
+       `int' to `int'.
+       (build_enumerator): In pedantic mode, cast to `int' those that
+       don't.
+
 2000-07-25  Rodney Brown  <RodneyBrown@pmsc.com>
 
        * config/alpha/osf.h (SIZE_TYPE, PTRDIFF_TYPE): New.
index c2bbb95c5fedcba3deff1e903ec8f61c896f630e..d80e3d4a5da9b379ba36f097287785f38391b84d 100644 (file)
@@ -5562,7 +5562,7 @@ finish_enum (enumtype, values, attributes)
      tree attributes;
 {
   register tree pair, tem;
-  tree minnode = 0, maxnode = 0;
+  tree minnode = 0, maxnode = 0, enum_value_type;
   int precision, unsign;
   int toplevel = (global_binding_level == current_binding_level);
 
@@ -5603,6 +5603,11 @@ finish_enum (enumtype, values, attributes)
       precision = TYPE_PRECISION (long_long_integer_type_node);
     }
 
+  if (precision == TYPE_PRECISION (integer_type_node))
+    enum_value_type = type_for_size (precision, 0);
+  else
+    enum_value_type = enumtype;
+
   TYPE_MIN_VALUE (enumtype) = minnode;
   TYPE_MAX_VALUE (enumtype) = maxnode;
   TYPE_PRECISION (enumtype) = precision;
@@ -5629,7 +5634,18 @@ finish_enum (enumtype, values, attributes)
          DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
          DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
          DECL_MODE (enu) = TYPE_MODE (enumtype);
-         DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
+
+         /* The ISO C Standard mandates enumerators to have type int,
+            even though the underlying type of an enum type is
+            unspecified.  Here we convert any enumerators that fit in
+            an int to type int, to avoid promotions to unsigned types
+            when comparing integers with enumerators that fit in the
+            int range.  When -pedantic is given, build_enumerator()
+            would have already taken care of those that don't fit.  */
+         if (int_fits_type_p (DECL_INITIAL (enu), enum_value_type))
+           DECL_INITIAL (enu) = convert (enum_value_type, DECL_INITIAL (enu));
+         else
+           DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
 
          TREE_PURPOSE (pair) = DECL_NAME (enu);
          TREE_VALUE (pair) = DECL_INITIAL (enu);
@@ -5706,7 +5722,7 @@ build_enumerator (name, value)
   if (pedantic && ! int_fits_type_p (value, integer_type_node))
     {
       pedwarn ("ANSI C restricts enumerator values to range of `int'");
-      value = integer_zero_node;
+      value = convert (integer_type_node, value);
     }
 
   /* Set basis for default for next value.  */