From 736f85c700aaa9ed3d9fd2f1d3ace131aaef12b3 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 26 Jul 2000 03:50:56 +0000 Subject: [PATCH] c-decl.c (finish_enum): Convert enumerations that fit in an `int' to `int'. * 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 | 7 +++++++ gcc/c-decl.c | 22 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5955a54e55..52399578e99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-07-26 Alexandre Oliva + + * 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 * config/alpha/osf.h (SIZE_TYPE, PTRDIFF_TYPE): New. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c2bbb95c5fe..d80e3d4a5da 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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. */ -- 2.30.2